Como criar tokens personalizados

Neste documento, você verá como usar o Identity Platform para criar JSON Web Tokens (JWTs) personalizados.

Os tokens personalizados oferecem controle total sobre o processo de autenticação. Gere esses tokens no servidor, transmita-os de volta para um dispositivo cliente e chame signInWithCustomToken() para fazer login dos usuários.

É possível criar tokens personalizados com o SDK Admin do Identity Platform ou usar uma biblioteca JWT de terceiros.

Antes de começar

  • Instale o SDK Admin. Se você estiver usando a descoberta automática de conta de serviço ou um ID de conta de serviço especificado explicitamente, verifique se a conta de serviço que você está usando tem pelo menos o papel Criador de token da conta de serviço (roles/iam.serviceAccountTokenCreator).

  • Criar e implantar um endpoint do servidor que aceite credenciais de login dos usuários.

Como criar tokens personalizados usando o SDK Admin

O SDK Admin tem um método integrado para criar tokens personalizados. Você precisa fornecer pelo menos um uid. Pode ser qualquer string que identifique de maneira exclusiva o usuário ou o dispositivo. Esses tokens expiram após uma hora.

O exemplo a seguir mostra como criar um token personalizado:

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

Depois de criar um token personalizado, o app poderá usá-lo para fazer login em um usuário.

Também é possível incluir reivindicações adicionais no token personalizado. Eles são propostos para o token de ID do usuário como declarações de nível superior.

O exemplo a seguir mostra como adicionar uma declaração premiumAccount:

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

O Identity Platform está em conformidade com a especificação JWT do OpenID Connect. Isso significa que as seguintes declarações são reservadas e não podem ser especificadas:

  • acr
  • amr
  • at_hash
  • aud
  • auth_time
  • azp
  • cnf
  • c_hash
  • exp
  • firebase
  • iat
  • iss
  • jti
  • nbf
  • nonce
  • sub

Como criar tokens personalizados usando uma biblioteca JWT de terceiros

Se seu back-end for gravado em uma linguagem que não é compatível com o SDK Admin, ainda será possível criar tokens personalizados manualmente. Primeiro, encontre uma biblioteca JWT de terceiros para sua linguagem. Em seguida, use essa biblioteca para criar um JWT que inclua as seguintes declarações:

alg Algoritmo "RS256"
iss Emissor Endereço de e-mail da conta de serviço do seu projeto.
sub Assunto Endereço de e-mail da conta de serviço do seu projeto.
aud Público-alvo "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
iat Hora de emissão A hora exata, em segundos desde a época de UNIX
exp tempo de expiração O tempo, em segundos, desde a época do UNIX, em que o token expira. Pode ser no máximo 3.600 segundos depois de iat.
Observe que isso controla apenas a hora em que o token personalizado expira. Depois que você fizer login de um usuário com o signInWithCustomToken(), ele permanecerá conectado até sair da sessão ou a sessão ser invalidada.
uid O identificador exclusivo do usuário conectado. Precisa ser uma string com 1 a 36 caracteres.
claims (opcional) Outras declarações personalizadas a serem incluídas.

Os exemplos a seguir demonstram como criar tokens personalizados em linguagens que não são compatíveis com o SDK Admin:

PHP

Usando 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

Como usar 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

Depois de criar um token personalizado, o app poderá usá-lo para fazer login em um usuário.

A seguir