Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase custom claim how to set?

I'm struggling with firebase custom claims.

I have tested a lot of approaches nothing works. Obviously, I miss something important in the concept itself.

So I'm back to the root. This script from the google example should apply customs rule on a newly created user

exports.processSignUp = functions.auth.user().onCreate(event => {
  const user = event.data; // The Firebase user.
  const customClaims = {
      param: true,
      accessLevel: 9
    };
  // Set custom user claims on this newly created user.
  return admin.auth().setCustomUserClaims(user.uid, customClaims)   

});

Then on a client, I check the result with

firebase.auth().currentUser.getIdTokenResult()
                .then((idTokenResult) => {
                    // Confirm the user is an Admin.
                    console.log(idTokenResult.claims)
                    if (!!idTokenResult.claims.param) {
                    // Show admin UI.
                    console.log("param")
                    } else {
                    // Show regular user UI.
                    console.log("no param")
                    }
                })
                .catch((error) => {
                    console.log(error);
                });

Everything just a raw copy-paste still doesn't work. I've tested both from the local machine(there could be troubles with cors?) and deployed

like image 660
Dmitriy Karpovich Avatar asked Feb 08 '19 14:02

Dmitriy Karpovich


People also ask

What is a custom user claim?

Custom claims are key/value pairs that you can set per user at the server level. They can be defined to give administrative privileges to access data and resources like you would need for apps with teachers and students, and provide multi-level access to data like you'd have in apps with paid and unpaid subscribers.

What is custom token authentication?

What Are Custom Authentication Tokens? An authentication token is some data, represented as a string or XML, that identifies an entity (user or process), such as an X509 client certificate. Typically, authentication tokens are designed to be used within specific security protocols.


2 Answers

This is a race situation. If the Function end first then, you will get the updated data.

The getIdTokenResult method does force refresh but if the custom claim is not ready then, it is pointless.

You need to set another data control structure to trigger the force refresh on the client. By example a real-time listener to the rtd;

root.child(`permissions/${uid}`).on..

And the logic inside the listener would be: if the value for that node exists and is a number greater than some threshold, then trigger the user auth refresh

During that time the ui can reflect a loading state if there is no datasnapshot or the not admin view if the datasnapshot exists but is a lower permission level.

In Functions you have to set the node after the claim is set:

..setCustomUserClaims(..).then(
    ref.setValue(9)
);

I have a more detailed example on pastebin

like image 129
cutiko Avatar answered Sep 30 '22 04:09

cutiko


The claims on the client are populated when the client gets an ID token from the server. The ID token is valid for an hour, after which the SDK automatically refreshes it.

By the time the Cloud Functions auth.user().onCreate gets called, the client has already gotten the ID token for the new user. This means that it can take up to an hour before the client sees the updated claims.

If you want the client to get the custom claims before that, you can force it to refresh the token. But in this video our security experts recommend (that you consider) using a different storage mechanism for claims that you want to be applied straight away.

like image 37
Frank van Puffelen Avatar answered Sep 30 '22 06:09

Frank van Puffelen