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 Cloud 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 Cloud Storage Security Rules.

You can create a custom token with the Firebase Admin SDK, 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 Admin SDK, you must have a service account. Follow the Admin SDK setup instructions for more information on how to initialize the Admin SDK with a service account.

Create custom tokens using the Firebase Admin SDK

The Firebase Admin SDK has 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. These tokens expire after one hour.

Node.js

var uid = "some-uid";

admin.auth().createCustomToken(uid)
  .then(function(customToken) {
    // Send token back to client
  })
  .catch(function(error) {
    console.log("Error creating custom token:", error);
  });

Java

String uid = "some-uid";

FirebaseAuth.getInstance().createCustomToken(uid)
    .addOnSuccessListener(new OnSuccessListener<String>() {
        @Override
        public void onSuccess(String customToken) {
            // Send token back to client
        }
    });

Python

uid = 'some-uid'

custom_token = auth.create_custom_token(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
};

admin.auth().createCustomToken(uid, additionalClaims)
  .then(function(customToken) {
    // Send token back to client
  })
  .catch(function(error) {
    console.log("Error creating custom token:", error);
  });

Java

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

FirebaseAuth.getInstance().createCustomToken(uid, additionalClaims)
    .addOnSuccessListener(new OnSuccessListener<String>() {
        @Override
        public void onSuccess(String customToken) {
            // Send token back to client
        }
    });

Python

uid = 'some-uid'
additional_claims = {
  'premiumAccount': True
}

custom_token = auth.create_custom_token(uid, additional_claims)

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

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

Android

mAuth.signInWithCustomToken(mCustomToken)
        .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    // Sign in success, update UI with the signed-in user's information
                    Log.d(TAG, "signInWithCustomToken:success");
                    FirebaseUser user = mAuth.getCurrentUser();
                    updateUI(user);
                } else {
                    // If sign in fails, display a message to the user.
                    Log.w(TAG, "signInWithCustomToken:failure", task.getException());
                    Toast.makeText(CustomAuthActivity.this, "Authentication failed.",
                            Toast.LENGTH_SHORT).show();
                    updateUI(null);
                }
            }
        });

Unity

auth.SignInWithCustomTokenAsync(custom_token).ContinueWith(task => {
  if (task.IsCanceled) {
    Debug.LogError("SignInWithCustomTokenAsync was canceled.");
    return;
  }
  if (task.IsFaulted) {
    Debug.LogError("SignInWithCustomTokenAsync encountered an error: " + task.Exception);
    return;
  }

  Firebase.Auth.FirebaseUser newUser = task.Result;
  Debug.LogFormat("User signed in successfully: {0} ({1})",
      newUser.DisplayName, newUser.UserId);
});

C++

firebase::Future<firebase::auth::User*> result =
    auth->SignInWithCustomToken(custom_token);

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 Cloud 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 (Cloud 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 Admin 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 that the Firebase Admin SDK does not support:

PHP

Using php-jwt:

// Requires: composer require firebase/php-jwt
use Firebase\JWT\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");
}

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.