Crear tokens personalizados

En este documento, se muestra cómo usar Identity Platform para crear tokens web JSON personalizados (JWT).

Los tokens personalizados te proporcionan un control completo del proceso de autenticación. Debes generar estos tokens en tu servidor, pasarlos a un dispositivo de cliente y, luego, llamar a signInWithCustomToken() para permitir que los usuarios accedan.

Puedes crear tokens personalizados con el SDK de administrador de Identity Platform o usar una biblioteca de JWT de terceros.

Antes de comenzar

  • Instala el SDK de Admin. Si usas el descubrimiento automático de cuentas de servicio o un ID de cuenta de servicio especificado explícitamente, asegúrate de que la cuenta de servicio que usas tenga, al menos, esa cuenta el rol de creador de tokens (roles/iam.serviceAccountTokenCreator).

  • Crea e implementa un extremo de un servidor que acepte credenciales de acceso de los usuarios.

Crea tokens personalizados mediante el SDK de Admin

El SDK de Admin tiene un método incorporado para crear tokens personalizados. Como mínimo, debes proporcionar un uid. Puede ser cualquier string que identifique de forma única al usuario o al dispositivo. Estos tokens vencen después de una hora.

En el siguiente ejemplo, se muestra cómo crear un 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

Después de crear un token personalizado, la aplicación puede usarlo para permitir que un usuario acceda.

De forma opcional, puedes incluir reclamaciones adicionales en el token personalizado. Estas se propagan al token de ID del usuario como reclamaciones de nivel superior.

En el siguiente ejemplo, se muestra cómo agregar una reclamación 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

Identity Platform cumple con la especificación de JWT de OpenID Connect. Esto significa que las siguientes reclamaciones están reservadas y no pueden especificarse:

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

Crea tokens personalizados con una biblioteca JWT de terceros

Si tu backend está escrito en un lenguaje que el SDK de Admin no admite, puedes crear tokens personalizados de forma manual. Primero, encontrar una biblioteca de JWT de terceros según tu idioma. Luego, usa esa biblioteca para crear un JWT en el que se incluyan las siguientes reclamaciones:

alg Algoritmo "RS256"
iss Emisor Dirección de correo electrónico de la cuenta de servicio del proyecto
sub Asunto Dirección de correo electrónico de la cuenta de servicio del proyecto
aud Público "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
iat Hora de emisión Hora actual, en segundos transcurridos desde el punto de inicio del tiempo UNIX
exp Hora de vencimiento Hora de vencimiento del token, en segundos transcurridos desde la época UNIX Puede ser un máximo de 3,600 segundos más tarde de iat.
Ten en cuenta que esto solo controla la hora de vencimiento del token personalizado. Una vez que permites que un usuario acceda con signInWithCustomToken(), su acceso permanecerá hasta que cierre la sesión o se invalide la sesión.
uid Identificador único del usuario que accedió (debe ser una string que contenga entre 1 y 36 caracteres)
claims (opcional) Son las reclamaciones personalizadas adicionales que deben incluirse.

En los siguientes ejemplos, se muestra cómo crear tokens personalizados en lenguajes que el SDK de Admin no admite:

PHP

Usa 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

Usa 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

Después de crear un token personalizado, la aplicación puede usarlo para permitir que un usuario acceda.

Próximos pasos