Minting Custom Tokens with the Admin SDK for Node.js – Firecasts

JEN PERSON: Hey, all
you Node.js developers. I’m Jen Person. And I’m going to show you how
to generate auth tokens using the Firebase Admin SDK. [MUSIC PLAYING] Firebase authentication has
some great built-in options for getting your users
logged into your app, such as email password
and Google authentication. But you also have the option
to use your own authentication scheme. You may already be using an
authentication scheme you like, or it may be a requirement
of your application to use some specific
form of authentication. Firebase gives you complete
control over authentication by allowing you to authenticate
users or devices using secure JSON Web Tokens,
pronounced “jot.” JWTs enable you to sign in with
custom authentication methods beyond those currently supported
by default in Firebase. One way to use JWTs
is to generate them on a secure server
that you manage, pass them back to
the client device, and then use them to
authenticate via sign-in custom token method. To achieve this, you must
create a server endpoint that accept sign-in credentials,
such as a username and password, and if the credentials are
valid, returns a custom JWT. The custom JWT returned
from your server can then be used
by a client device to authenticate with Firebase
on iOS, Android, or web. Once authenticated
the token can be used for accessing
other Firebase services, such as Firebase Realtime
Database and cloud storage. Today, I’ll show you how
to create a JWT using the Admin SDK for Node.js. But you can also create
a JWT using the Admin SDK for Java, Python, and Go. Let’s get started by adding
and initializing the SDK. First, I need service
account credentials, which I can download from
the Firebase console. Under the Firebase
Admin SDK tab, I’ll select Generate
New Private Key. This downloads a JSON file
containing the service account credentials. I’ll add this to my
Projects directory. Now I’ll install the
Firebase Admin package in my Project directory. I’ll require the
Firebase Admin package. I’ll also require the config
file containing the service account key. Then I can initialize the SDK
using my downloaded service account key file. The Firebase Admin SDK
provides a mechanism for creating custom tokens. These tokens expire
after one hour. But once you sign in a user
using signInWithCustomToken, they will remain
signed into the device until their session
is invalidated or the user signs out. Tokens expire to prevent someone
from authenticating forever to the app once they
logged in at least once. You need to provide a UID, which
can be any string that uniquely identifies the user or device
you are authenticating. Once the token is
returned to the client, if the authentication
succeeds, your user will be now signed
into your client app with the account specified in
the UID included in the custom token. If a Firebase account
with a given UID did not previously exist,
a record for that user will be created with the
UID provided by the token. You can also include
claims, which can customize what data
the client can access. I’ll show you what
that looks like, too, using an iOS app I made that
displays a special photo and message to users who
upgrade to premium content. Let’s get going on the code
to create custom tokens. I’ll create a variable
to hold the UID I will pass as a parameter when
creating the custom token. Since the UID can
be any string, I’ll just make it some-uid for now. I’ll call the auth function on
the admin object, which gives me the auth service instance. This auth instance includes
the method createCustomToken, which I’ll call, passing
the UID as a parameter. The function returns
a promise that resolves with a
custom JWT, which I can send back to the client. But for now, I’m just
going to log the token. I’ll also include a catch
block and handle the error. And for the sake of this demo,
again, I’ll just log the error. Now, you also have the
option to include claims in the custom token. Here, I’ll adding additional
claims to the custom token, setting premiumAccount to true. This will be available in the
auth object in my database security rules and
my request.authObject in my stored security rules. Say I have some
content in my database that I want to restrict
to only premium accounts. I can allow access to that data
by checking the premium account claim in the security
rules, like this. I can store data in a
database under a child called premiumContent and
enable read access to this child for any user
whose token allows it. I can do something similar
with cloud storage. Here, I’m using the
premiumAccount claim to configure rules
like this one, restricting some
files in cloud storage to users with a
premiumAccount claim. I’ve included some content in my
database and cloud storage that is only accessible if the auth
token’s premiumAccount claim is set to true. So first, let’s run the function
without the claim and then with it to see how access to the
content changes for the client. To test my function, I’m going
to run it, generate a UID, and then use the resulting
token to authenticate in this simple iOS app I made. And you can see a new user
was created in the database. I can also create a custom
token from an existing UID and sign in from the client. I’ll copy the UID, paste it into
my code where I had some-uid. Now I’m signed in as this
test user I made earlier. But as you can see,
I get a message saying I need to sign
up for a premium account to see custom content. If I go back to my code
and include the claim, premiumAccount, and
run my code again, I can use this custom
token to sign in. And you can see content only
visible to a premium account. And there you have it. Now you can create custom
tokens that the client can use to sign in and
access Firebase features. Remember to subscribe
to the Firebase channel to find out about the latest
“Firecasts” and other Firebase YouTube series, including
my series, “Ask Firebase.” I’ll see you on a future
episode of “Firecasts.” [MUSIC PLAYING]

Danny Hutson

Leave a Reply

Your email address will not be published. Required fields are marked *