Crear tokens personalizados

En este documento se explica cómo usar Identity Platform para crear JSON Web Tokens (JWTs) personalizados.

Los tokens personalizados te permiten controlar por completo el proceso de autenticación. Estos tokens se generan en tu servidor, se devuelven a un dispositivo cliente y, a continuación, se llama a signInWithCustomToken() para iniciar la sesión de los usuarios.

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

Antes de empezar

  • Instala el SDK Admin. Si usas la detección automática de cuentas de servicio o un ID de cuenta de servicio especificado explícitamente, asegúrate de que la cuenta de servicio que utilices tenga al menos el rol Creador de tokens de cuenta de servicio (roles/iam.serviceAccountTokenCreator).

  • Crea e implementa un endpoint de servidor que acepte las credenciales de inicio de sesión de los usuarios.

Crear tokens personalizados con el SDK de administrador

El SDK de administrador tiene un método integrado para crear tokens personalizados. Como mínimo, debes proporcionar un uid. Puede ser cualquier cadena que identifique de forma única al usuario o al dispositivo. Estos tokens caducan al cabo 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

Una vez que hayas creado un token personalizado, tu aplicación podrá usarlo para iniciar la sesión de un usuario.

Si quieres, puedes incluir reclamaciones adicionales en el token personalizado. Se propagan al token de ID del usuario como reclamaciones de nivel superior.

En el siguiente ejemplo se muestra cómo añadir una reclamación de 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 la especificación JWT de OpenID Connect. Esto significa que las siguientes reclamaciones están reservadas y no se pueden especificar:

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

Crear tokens personalizados con una biblioteca JWT de terceros

Si tu backend está escrito en un lenguaje que no admite el SDK de administrador, puedes crear tokens personalizados manualmente. Primero, busca una biblioteca JWT de terceros para tu idioma. A continuación, usa esa biblioteca para generar un JWT que incluya las siguientes reclamaciones:

alg Algoritmo "RS256"
iss Emisor La dirección de correo de la cuenta de servicio de tu proyecto.
sub Asunto La dirección de correo de la cuenta de servicio de tu proyecto.
aud Audiencia "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
iat Hora de emisión La hora actual, en segundos, desde el inicio del registro de tiempo de Unix.
exp Plazo de vencimiento Hora, en segundos desde la época de UNIX, en la que caduca el token. Puede ser hasta 3600 segundos después de la iat.
Ten en cuenta que esto solo controla el momento en el que caduca el token personalizado. Una vez que un usuario inicia sesión con signInWithCustomToken(), su sesión seguirá iniciada hasta que cierre la sesión o hasta que la sesión deje de ser válida.
uid Identificador único del usuario que ha iniciado sesión. Debe ser una cadena de entre 1 y 36 caracteres.
claims (opcional) Reclamaciones personalizadas adicionales que quieras incluir.

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

PHP

Usar 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

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

Una vez que hayas creado un token personalizado, tu aplicación podrá usarlo para iniciar la sesión de un usuario.

Siguientes pasos