Firebase Auth Custom Claims with Angular

September 9, 2018
cgrant

Firebase Auth Custom Claims with Angular

3. Auth - Advanced

see also https://javebratt.com/firestore-functions/

It’s a better practice to move the auth logic to the backend

Couple points to review

  • Functions method triggers on user creation
  • Custom JWT Claims to store roles
  • Securing Firestore with claims

Functions

Fucntions includes a hook to execute on user creation. Use this to set some base roles, send welcome email etc.

functions.auth.user().onCreate()

https://firebase.google.com/docs/auth/extend-with-functions#trigger_a_function_on_user_creation

Custom claims

The JWT Token can be create with custom info. This data can be stored and pulled from firestore. This would be done through the admin.auth().setCustomUserClaims() method, the claims are update after this in the JWT by forcing a refresh using user.getIdToken(true);

https://firebase.google.com/docs/auth/admin/custom-claims#defining_roles_via_firebase_functions_on_user_creation

https://firebase.google.com/docs/auth/admin/custom-claims#examples_and_use_cases

firebase init

chose functions

Edit index.ts in the functions directory

import * as functions from 'firebase-functions';

// // Start writing Firebase Functions
// // https://firebase.google.com/docs/functions/typescript
//
// export const helloWorld = functions.https.onRequest((request, response) => {
//  response.send("Hello from Firebase!");
// });


const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

// On sign up.
exports.processSignUp = functions.auth.user().onCreate(event => {
  const user = event; // The Firebase user.
  // Check if user meets role criteria.
 
    
    const customClaims = {
        admin: true,
        accessLevel: 9
      };
      // Set custom user claims on this newly created user.
     
      admin.auth().setCustomUserClaims(user.uid, customClaims);
      return user;

});

deploy the function

firebase deploy --only functions

Firestore Security

At this point your jwt will include the new roles you’ve added. You can then secure your database checking for values direclty on the token such as request.auth.token.admin as in allow read, write: if request.auth.token.admin OR allow read, write: if request.auth.token.accessLevel > 10;


service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {

      function isAdmin() {
            // return request.auth.token.accessLevel > 8;
    		return request.auth.token.admin;
      }

      allow read, write: if isAdmin();
      
    }
  }
}