README
@teku-blocks/react-auth
Simple solution to make your React web application authentication / authorization. Designed to work with Auth0, Firebase v8 and Firebase v9.
Table of contents
Installation
npm install --dev @teku-blocks/react-auth
Install other dependencies
npm install --dev @auth0/auth0-spa-js kind-of eventemitter3
Concept
There are 3 supported auth drivers:
- Auth0: Using auth0, or even in combination with Firebase Auth
- FirebaseAuth: Using Google Firebase Auth
- FireseProfile: Fetching user profile from Google [Firestore][service-firestore]
After initialization, these drivers will automatically handle authentication / authorization logic for you, the resolved profiles will be pushed into AuthContext through their driver ids and even trigger event handlers for us.
How To Use
Handle auth with AuthProvider
We provide AuthProvider
for wrapping your components / pages, which will automatically handle authentication process for you.
import { AuthProvider } from '@teku-blocks/react-auth'
<AuthProvider {...options}>
{children}
</AuthProvider>
There are 2 types of options:
All of options are optional, but as least 1 driver options should be provided. Option syntaxes / signatures are described using Typescript style or detailed tables in following sections.
Callbacks
onUserChanged
(driver: AuthDrivers, user: any | null) => void
This callback is fired everytime auth data changed, when the users are logged in, or logged out (null
).
The driver
param are driver id (like auth0, firebase...) that has auth data updated.
onError
(driver: AuthDrivers, err: Error) => void
This callback is only fired when error happens.
Driver options
The driver options (objects) will be used to initialize authentication clients.
withAuth0
These are only options which is required or provided with default values. More auth0 options can be found at Auth0 options
Option | Type | Description | Default |
---|---|---|---|
domain | string | required Domain registed with Auth0 more info |
|
clientId | string | required Auth0 client id more info |
|
redirectUri | string | required Callback after Auth0 authentication more info |
|
responseType | string | Response type | token id_token |
scope | string | Scope | openid profile email |
Authenticated Auth0 profile contains these fields:
_token
: auth token_tokenExpiresAt
: token expiration timestampemail
: user emailemailVerified
: where the user email has been verifiedname
: user namepicture
: URL to user picture
withFirebaseAuth
These are options of Firebase auth driver:
Option | Type | Description | Default |
---|---|---|---|
auth | [Auth][#firebase-auth] | required Firebase auth instance |
|
onAuthStateChanged | (user: any or null ) => void |
required Callback whenever firebase auth user logged in / logged out (null ) |
|
customClaimMap | any | Map fields from custom claims into solved user | {} |
customTokenMap | any | Provide fields to be used during custom token exchanges when you combine firebase with auth0 more info | { inputName: 't', outputName: 'ct' } |
getCustomToken | (token: string) => Promise<string> | Only required when you combine firebase with auth0, async function to resolve with custom token more info |
|
withAuth0 | boolean | Whether should firebase combine with auth0 | true |
Authenticated FirebaseAuth profile contains these fields:
_token
: auth tokenuid
: user's uidemail
: user emailemailVerified
: where the user email has been verifiedphoneNumber
: user associated phone numbername
: user namecustom
claim fieldspicture
: URL to user picture
Apart from _token
, uid
and picture
, other fields are standardized to be used as Firebase security rules more info.
withFirebaseProfile
This driver requires withFirebaseAuth
to be setup, it will watch for firebase auth data changed to determine when to fetch necessary profile, to login and logout.
Option | Type | Description | Default |
---|---|---|---|
getQuery | (conditions: any) => Query | required A function to return a Firestore Query for filter user profile, since we only take first found document, a query with limit(1) is recommended |
|
getSnapshot | (query: Query, onChange: Function, onError: Function) => Unsubscribe | required A function to start watching profiles query snapshot. Usually we will need to bind onChange and onError to snapshot creator. For example query.onSnapshot(onChange, onError) |
|
userIdField | string | User id field for adding into conditions | uid |
criteria | any | Additional criteria to filter profile data with firebase user id |
Access auth data with AuthContext
We profile a React hook to listen for auth data context changes
import { useAuth } from '@teku-blocks/react-auth`
const auth = useAuth()
The auth
context value presents authentication state of all available drivers:
{[key in AuthDrivers]}: any}
Render based on authentication status
We provide a handy AuthGate
ultility component for toggling display based on authentication state. In this example, FallbackComponent
is displayed if user isn't authenticated yet:
import { AuthGate } from '@teku-blocks/react-auth`
<AuthGate FallbackComponent={() => 'Please login'}>
{/* something to hide if user not authenticated */}
</AuthGate>
If you want to show something else instead of FallbackComponent
while the application is determining if user is authenticated or not (due to async flow), the MaskComponent
option can be used as a placeholder during this process:
import { AuthGate } from '@teku-blocks/react-auth`
<AuthGate
FallbackComponent={() => 'Please login'}
MaskComponent={() => 'Verifying your authentication ...'}
>
{/* something to hide if user not authenticated */}
</AuthGate>
Using Auth0 with Firebase
For combine Auth0 with Firebase, we need to setup a cloud function for using Firebase Admin SDK to create custom tokens.
Here is an example of getCustomToken
function:
const getCustomToken = async token => {
const exchangeToken = firebase.functions().httpsCallable('auth')
const { data } = exchangeToken({ t: token })
return data.token
}
After auth0 done authenticated a user, if the user's email has been verified, react-auth
will try to authenticate the user through custom tokens, hence allow the user to access firebase resources.
List of available driver ids
The full list of supported driver ids can be found in AuthDrivers
enum. You can use them to determine with part of auth data is being initalized
enum AuthDrivers {
AUTH0 = 'auth0',
FIREBASE_AUTH = 'firebase',
FIREBASE_PROFILE = 'profile'
}
Contribution
All contributions are welcome. Feel free to open PR or share your ideas of improvement.
Thank you.