Creating custom tokens
This document shows you how to use Identity Platform to create custom JSON Web Tokens (JWTs).
Custom tokens give you complete control over the authentication process. You
generate these tokens on your server, pass them back to a client device, and
then call signInWithCustomToken()
to sign in users.
You can create custom tokens with the Identity Platform Admin SDK, or use a third-party JWT library.
Before you begin
Install the Admin SDK. If you are using service account auto-discovery or an explicitly specified service account ID, make sure the service account you are using has at least the Service Account Token Creator (
roles/iam.serviceAccountTokenCreator
) role.Create and deploy a server endpoint that accepts sign-in credentials from users.
Creating custom tokens using the Admin SDK
The Admin SDK has a built-in method for creating custom tokens. At a
minimum, you need to provide a uid
. This can be any string that uniquely
identifies the user or device. These tokens expire after one hour.
The following example shows how to create a custom token:
Node.js
const uid = 'some-uid'; getAuth() .createCustomToken(uid) .then((customToken) => { // Send token back to client }) .catch((error) => { console.log('Error creating custom token:', error); });
Java
String uid = "some-uid"; String customToken = FirebaseAuth.getInstance().createCustomToken(uid); // Send token back to client
Python
uid = 'some-uid' custom_token = auth.create_custom_token(uid)
Go
client, err := app.Auth(context.Background()) if err != nil { log.Fatalf("error getting Auth client: %v\n", err) } token, err := client.CustomToken(ctx, "some-uid") if err != nil { log.Fatalf("error minting custom token: %v\n", err) } log.Printf("Got custom token: %v\n", token)
C#
var uid = "some-uid"; string customToken = await FirebaseAuth.DefaultInstance.CreateCustomTokenAsync(uid); // Send token back to client
After you create a custom token, your app can use it to sign in a user.
Optionally, you can include additional claims on the custom token. These are propagated to the user's ID token as top-level claims.
The following example shows how to add a premiumAccount
claim:
Node.js
const userId = 'some-uid'; const additionalClaims = { premiumAccount: true, }; getAuth() .createCustomToken(userId, additionalClaims) .then((customToken) => { // Send token back to client }) .catch((error) => { console.log('Error creating custom token:', error); });
Java
String uid = "some-uid"; Map<String, Object> additionalClaims = new HashMap<String, Object>(); additionalClaims.put("premiumAccount", true); String customToken = FirebaseAuth.getInstance() .createCustomToken(uid, additionalClaims); // Send token back to client
Python
uid = 'some-uid' additional_claims = { 'premiumAccount': True } custom_token = auth.create_custom_token(uid, additional_claims)
Go
client, err := app.Auth(context.Background()) if err != nil { log.Fatalf("error getting Auth client: %v\n", err) } claims := map[string]interface{}{ "premiumAccount": true, } token, err := client.CustomTokenWithClaims(ctx, "some-uid", claims) if err != nil { log.Fatalf("error minting custom token: %v\n", err) } log.Printf("Got custom token: %v\n", token)
C#
var uid = "some-uid"; var additionalClaims = new Dictionary<string, object>() { { "premiumAccount", true }, }; string customToken = await FirebaseAuth.DefaultInstance .CreateCustomTokenAsync(uid, additionalClaims); // Send token back to client
Identity Platform complies with the OpenID Connect JWT specification. This means the following claims are reserved and cannot be specified:
acr
amr
at_hash
aud
auth_time
azp
cnf
c_hash
exp
firebase
iat
iss
jti
nbf
nonce
sub
Creating custom tokens using a third-party JWT library
If your backend is written in a language that the Admin SDK doesn't support, you can still manually create custom tokens. First, find a third-party JWT library for your language. Then, use that library to mint a JWT which includes the following 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 that this only controls the time when the custom token itself expires. Once you sign in a user with signInWithCustomToken() , they will remain signed in until
they sign out or their session is invalidated.
|
uid |
The unique identifier of the signed-in user. Must be a string between 1-36 characters long. | |
claims (optional) |
Additional custom claims to include. |
The following examples demonstrate how to create custom tokens in languages the 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 a custom token, your app can use it to sign in a user.
What's next
- Sign in users with custom tokens.
- Configure custom claims on users.
- Use the REST API to integrate Identity Platform with other parts of your custom authentication system.