Create Custom Tokens

Firebase gives you complete control over authentication by allowing you to authenticate users or devices using secure JSON Web Tokens (JWTs). You generate these tokens on your server, pass them back to a client device, and then use them to authenticate via the signInWithCustomToken() method.

To achieve this, you must create a server endpoint that accepts 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 (iOS, Android, web). Once authenticated, this identity will be used when accessing other Firebase services, such as the Firebase Realtime Database and Firebase Storage. Furthermore, the contents of the JWT will be available in the auth object in your Firebase Realtime Database Security Rules and the request.auth object in your Firebase Storage Security Rules.

You can create a custom token with the Firebase Server SDKs for Java and Node.js, or you can use a third-party JWT library if your server is written in a language which Firebase does not natively support.

Before you begin

To create custom tokens with the Firebase server SDKs, you must have a service account. Follow the server SDK setup instructions for more information on how to initialize your server SDK with a service account.

Create custom tokens using the Firebase SDK

The Firebase server SDKs have a built-in method for creating custom tokens. At a minimum, you need to provide a uid, which can be any string but should uniquely identify the user or device you are authenticating.

Node.js

var uid = "some-uid";
var customToken = firebase.auth().createCustomToken(uid);

Java

String uid = "some-uid";
String customToken = FirebaseAuth.getInstance().createCustomToken(uid);

You can also optionally specify additional claims to be included in the custom token. For example, below, a premiumAccount field has been added to the custom token, which will be available in the auth / request.auth objects in your Security Rules:

Node.js

var uid = "some-uid";
var additionalClaims = {
  premiumAccount: true
};
var token = firebase.auth().createCustomToken(uid, additionalClaims);

Java

String uid = "some-uid";
HashMap<String, Object> additionalClaims = new HashMap<String, Object>();
additionalClaims.put("premiumAccount", true);
token = FirebaseAuth.getInstance().createCustomToken(uid, additionalClaims);

Sign in using custom tokens on clients

After you create a custom token, you should send it to your client app. The client app authenticates with the custom token by calling signInWithCustomToken():

iOS

Objective-C

[[FIRAuth auth] signInWithCustomToken:customToken
                           completion:^(FIRUser *_Nullable user,
                                        NSError *_Nullable error) {
                             // ...
                           }];

Swift

FIRAuth.auth()?.signIn(withCustomToken: customToken ?? "") { (user, error) in
  // ...
}

Android

mAuth.signInWithCustomToken(mCustomToken)
        .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                Log.d(TAG, "signInWithCustomToken:onComplete:" + task.isSuccessful());

                // If sign in fails, display a message to the user. If sign in succeeds
                // the auth state listener will be notified and logic to handle the
                // signed in user can be handled in the listener.
                if (!task.isSuccessful()) {
                    Log.w(TAG, "signInWithCustomToken", task.getException());
                    Toast.makeText(CustomAuthActivity.this, "Authentication failed.",
                            Toast.LENGTH_SHORT).show();
                }
            }
        });

Web

firebase.auth().signInWithCustomToken(token).catch(function(error) {
  // Handle Errors here.
  var errorCode = error.code;
  var errorMessage = error.message;
  // ...
});

If the authentication succeeds, your user will be now signed in into your client app with the account specified by the uid included in the custom token. If that account did not previously exist, a record for that user will be created.

In the same way as with other sign-in methods (such as signInWithEmailAndPassword() and signInWithCredential()) the auth object in your Firebase Realtime Database Security Rules and the request.auth object in your Firebase Storage Security Rules will be populated with the user's uid. In this case, the uid will be the one that you specified when generating the custom token.

Database Rules

{
  "rules": {
    "adminContent": {
      ".read": "auth.uid === 'some-uid'"
    }
  }
}

Storage Rules

service firebase.storage {
  match /b/<your-firebase-storage-bucket>/o {
    match /adminContent/{filename} {
      allow read, write: if request.auth.uid == "some-uid";
    }
  }
}

If the custom token contains additional claims, they can be referenced off of the auth.token (Firebase Realtime Database) or request.auth.token (Firebase Storage) object in your rules:

Database Rules

{
  "rules": {
    "premiumContent": {
      ".read": "auth.token.premiumAccount === true"
    }
  }
}

Storage Rules

service firebase.storage {
  match /b/<your-firebase-storage-bucket>/o {
    match /premiumContent/{filename} {
      allow read, write: if request.auth.token.premiumAccount == true;
    }
  }
}

Create custom tokens using a third-party JWT library

If your backend is in a language that doesn't have an official Firebase server SDK, you can still manually create custom tokens. First, find a third-party JWT library for your language. Then, use that JWT library to mint a JWT which includes the following claims:

Custom Token Claims
alg Algorithm "RS256"
iss Issuer Your project's service account email address
sub Subject Your project's service account email address
aud Audience "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
iat Issued-at time The current time, in seconds since the UNIX epoch
exp Expiration time The time, in seconds since the UNIX epoch, at which the token expires. It can be a maximum of 3600 seconds later than the iat.
Note: this only controls the time when the custom token itself expires. But once you sign a user in using signInWithCustomToken(), they will remain signed in into the device until their session is invalidated or the user signs out.
uid The unique identifier of the signed-in user must be a string, between 1-36 characters long
claims (optional) Optional custom claims to include in the Security Rules auth / request.auth variables

Here are some example implementations of how to create custom tokens in a variety of languages for which official Firebase server SDKs do not exist:

PHP

Using php-jwt:

// Get your service account's email address and private key from the JSON key file
$service_account_email = "abc-123@a-b-c-123.iam.gserviceaccount.com";
$private_key = "-----BEGIN PRIVATE KEY-----...";

function create_custom_token($uid, $is_premium_account) {
  global $service_account_email, $private_key;

  $now_seconds = time();
  $payload = array(
    "iss" => $service_account_email,
    "sub" => $service_account_email,
    "aud" => "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
    "iat" => $now_seconds,
    "exp" => $now_seconds+(60*60),  // Maximum expiration time is one hour
    "uid" => $uid,
    "claims" => array(
      "premium_account" => $is_premium_account
    )
  );
  return JWT::encode($payload, $private_key, "RS256");
}

Python

Using the python-jwt and pycrypto packages:

import jwt  # Requires: pip install python-jwt
import Crypto.PublicKey.RSA as RSA  # Requires: pip install pycrypto

import datetime

# Get your service account's email address and private key from the JSON key file
service_account_email = "service-account@my-project-abc123.iam.gserviceaccount.com"
private_key = RSA.importKey("-----BEGIN PRIVATE KEY-----\n...")

def create_custom_token(uid, is_premium_account):
  try:
    payload = {
      "iss": service_account_email,
      "sub": service_account_email,
      "aud": "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
      "uid": uid,
      "claims": {
        "premium_account": is_premium_account
      }
    }
    exp = datetime.timedelta(minutes=60)
    return jwt.generate_jwt(payload, private_key, "RS256", exp)
  except Exception as e:
    print "Error creating custom token: " + e.message
    return None

Ruby

Using ruby-jwt:

require "jwt"

# Get your service account's email address and private key from the JSON key file
$service_account_email = "service-account@my-project-abc123.iam.gserviceaccount.com"
$private_key = OpenSSL::PKey::RSA.new "-----BEGIN PRIVATE KEY-----\n..."

def create_custom_token(uid, is_premium_account)
  now_seconds = Time.now.to_i
  payload = {:iss => $service_account_email,
             :sub => $service_account_email,
             :aud => "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
             :iat => now_seconds,
             :exp => now_seconds+(60*60), # Maximum expiration time is one hour
             :uid => uid,
             :claims => {:premium_account => is_premium_account}}
  JWT.encode payload, $private_key, "RS256"
end

After you create the custom token, send it to your client app to use to authenticate with Firebase. See the code samples above for how to do this.

Send feedback about...

Need help? Visit our support page.