Jon Rumsey

An online markdown blog and knowledge repository.


Project maintained by nojronatron Hosted on GitHub Pages — Theme by mattgraham

Google Firebase Authentication

"Provides backend services, easy-to-use SDK's, and ready-made UI libraries to authenticate users to your app." [Firebase Authentication Google Documentation]

Overview

FirebaseUI Auth

Firebase SDK Auth

Firebase Auth with ID Platform

Usage Limits

WebDev Simplified Setup Overview

Source: WebDev Simplified: Crash Course with Firebase and Routing.

  1. Create Firebase Auth Projects: One for Dev, one for Production (if needed).
  2. Create your Firebase Auth App within the Project to get the 'firebaseConfig' data.
  3. Create ReactApp.
  4. Setup an ENV file and add all 'firebaseConfig' data there. Prefix all Env keys with 'REACT_'.
  5. Install 'firebase' using NPM.
  6. Add a firebase.js file, import firebase/app and firebase/auth.
  7. Add a const firebase.initializeApp and use process.env.REACT_NAME_OF_EACH_ENV_ENTRY to load the settings. Export as default.
  8. Create a Signup.js React functional component. This page should include the ability to Register using a link or Login using an on-screen Form. Include a password confirmation input too! Don't forget a Submit button with value 'Sign up'. One way to grab data from Forms is to import {useRef} from 'react' and assign Refs variable names so React can use them. useRef variables can be referenced using refName.current.value.
  9. Create a folder called 'context' to store Context so the authentication can be used anywhere within the ReactApp.
  10. Create an AuthContent.js React Functional Component. Assign const AuthContext = React.createContext() to allow wrapping the function export 'children' within an AuthCotext.Provider tag. (16:46 minutes into video). There is more setup here where useState is utilized to store the AuthProvider is set up.
  11. Import firebase/auth into AuthContent.js. Add a signup function using auth.createUserWithEmailAndPassword(). The function will now return currentUser and signup functions.
  12. Import contexts/AuthContext into the Signup React Functional Component.
  13. Ensure the entire App (inside App.js return() statement) is wrapped with <AuthProvider>.
  14. Validate user inputs! Exit out of a handleSubmit function if the input validation fails, and return a helpful error message (return setError('Passwords do not match')).
  15. Ensure rendering doesn't happen until Firebase can return with the user info. There is a lot to this, including use of useEffect and useState.
  16. Import BrowserRouter (a react-router-dom component) to App.js, and include 'Switch' and 'Route'. Router component will live inside the App rendered Container, and AuthProvider will live inside of the parent Router component.
  17. Enable routes by adding <Route path='/path' component={component} /> and wrapping them all with <Switch>.
  18. Create a Login component that is A LOT like the Signup Component, except will leverage wrapped Login function from Firebase Auth component.
  19. Use ReactRouter's <Link> component to enable linking text from one page (e.g. Login) to another (e.g. Signup).
  20. Leverage 'useHistory' from React Router to 'push' to a specific page (or '/') as a way to redirect after registration, login, or logout.
  21. Create a profile (dashboard) with a new React Functional Component. Replicate the work done in the login/register pages but only include a Logout button, and instead of displaying a Form for user to enter data, use elements to display data about the currently logged on user (const { currentUser } = useAuth()).
  22. Optionally configure a link to update the user profile that <Link to='/update-profile'>Update Profile</Link> using React Router's 'Link' component.
  23. Create a custom component called 'PrivateRoute.js'. It's a new React Functional Component. Export a function PrivateRouter({ component: Component, ...rest }) that just returns <Route {...rest}></Route> and a render= that captures the arrow function that checks for 'currentUser' to render component that got us here, otherwise redirect (via React Router) to the Login page.
  24. At the bottom of the Log In page, add a div to contain a link to 'forgot password' page.
  25. Create a Route for Forgot Password in the Route list in App.js.
  26. Create a new React Functional Component ForgotPassword.js and copy 'Login' component code (except the password expressions and variables), update text to set 'Forgot Password' context for the user, and implement a wrapper function resetPassword(email){} that just returns auth.sendPasswordResetEmail(email).
  27. Complete the Profile/Dashboard page, and utilize useAuth() hook to allow Email and Password changes.

Sign-in User To An App

  1. Get auth credentials from user (UN+PW or OAuth Token).
  2. Pass credentials to Firebase Authentication SDK.
  3. Firebase backend services verify credentials and return response to client.

User Profiles

After authentication:

Verify ID Tokens

A custom backend server can verify a user's Firebase Auth Token:

  1. Front-end app verifies user and logs them in.
  2. Front-end app opens a connection to the back-end using HTTPS.
  3. Back-end server receives the user's ID token and verifies its authenticity to get the user's UID.
  4. Back-end server uses the UID to securely ID the currently signed-in user.

Verify ID Tokens in Firebase Authentication.

On the Back End (More Info)

  1. Setup Firebase with a Google Application Credential (json file) and Firebase Project ID. Use DotEnv for example.
  2. Install firebase-admin (I used ^11.4.1).
  3. Implement middleware that imports firebase-admin, dotenv (for example) and setup a 'serviceAccount' variable that requires the Google App Creds.
  4. Middleware: admin.initializeApp({ credential: admin.credential.cert(serviceAccount)});
  5. Middleware: Implement a 'getAuthToken(req, res, next)' function that gets the 'Bearer token', and calls 'next();` at the end (as middleware does).
  6. Middleware: Implement a 'checkAuthentication(req, res, next)' function that calls 'getAuthToken' then within a try-catch uses admin.auth().verifyIdToken(authToken) to validate the token then return 'next()' or an error (if 'catch(error)' is executed, then setting status code 401 and an error message i.e. 'unauthorized') else set 200 like status code.
  7. On each path that requires authentication, insert 'checkIfAuthenticated' exported module function in the middleware, so Express will disallow or authorize access to the code next in the middleware chain.

Optional: Use and refresh session cookies when 'checkIfAuthenticated' passes, otherwise expire the cookie.

Implementation - FirebaseUI Auth

  1. Setup sign-in method(s): Firebase console configuration; setup OAuth redirect URL.
  2. Customize sign-in UI: Set FirebaseUI options (or fork OSS and customize from there).
  3. Perform Sign-in Flow: FirebaseUI Library configures sign-in methods support and flow.

Firebase JS SDK 9 Setup

Overview Video Notes

Generally:

To programmatically create a user account:

Best Practice: Use a Login State Monitor function that will return correct feedback to users on the login screen.

Walk-thru with Code Samples

  1. Add and Init Auth SDK.
  2. Prototype and test with Firebase Local Emulator Suite (optional).
  3. Sign-up new users.
  4. Sign-in existing users.
  5. Set an authentication state observer and get user data.

Source: Firebase Docs Auth Web Start

Dev Setup and Management

Firebase Tools and Firebase-CLI are needed for enabling the firebase emulator environment.

Documentation for install and configure.

Local Auth Emul Config

Note: Admin SDKs can be automatically connected using a ENV file. See firebase docs emulator connect authentication web version 9 for details.

Final step to start the emulator processes:

File System Changes After Dev Setup and Emulator Install

Added:

Changed:

Emulator Startup Info

Running a local emulator is optional, but can serve as a local dev & test platform without relying on a 'production' Firebase Auth App instance or setting up a second app.

When starting the emulator(s) (firebase emulators:start):

Note: Left off here.

Authorized Domains

In the Firebase Auth project, defaults will be entered for you.

For development, localhost will be allowed.

For production, localhost should be deleted!

Using Google Auth

  1. Add Firebase to the JS project if not already.
  2. Enable Google as sign-in provider to Firebase Project (a new public-facing project name will be added and a Project Support Email will be required).
  3. Implement Google Sign-in Flow using Firebase SDK into the project.

Implement Google Sign In Flow

  1. Create a Google Provider object that imports GoogleAuthProvider from firebase/auth, and calls 'new GoogleAuthProvider()'.
  2. Optional: Add OAuth 2.0 scopes using provider.addScope(googleapis.com/my_scope).
  3. Optional: Localize OAuth flow to user's preferred language.
  4. Optional: Specify custom OAuth provider params to send with OAuth Request: provider.setCustomParameters({ 'key': 'value' }).
  5. Use the Google Provider Object to authenticate the user with Firebase. A Pop-up can be used or a redirect to the sign-in page (redirect preferred on mobile).
  6. Call getRedirectResult(auth) to acquire the provider's OAuth token when the page loads.

Google ID OAuth 2.0 Scopes

Check out OAuth 2.0 Scopes for Google APIs

Notes About Google Sign In Flow using Nodejs

Firebase documentation states this sign-in flow must be handled manually:

  1. Implement sign-in flow to get user's Google ID token.
  2. Build a Credential Object using Google ID Token.
  3. Call signInWithCredential(auth, credential)... (more code here so see the web link) to perform login and handle any error.

Overall:

Note: Bearer token appears to be stored in local browser's firebaseLocalStorage (browser LocalStorage) at: value > stsTokenManager > accessToken.

Resources

Return to Conted Index

Return to Root README