创建自定义令牌
本文档介绍如何使用 Identity Platform 创建自定义 JSON Web 令牌 (JWT)。
自定义令牌可让您完全控制身份验证过程。您可以在自己的服务器上生成这些令牌,将它们传递回客户端设备,然后调用 signInWithCustomToken()
让用户登录。
您可以通过 Identity Platform Admin SDK 创建自定义令牌,也可以使用第三方 JWT 库。
准备工作
安装 Admin SDK。如果您使用的是服务账号自动发现功能或明确指定的服务账号 ID,请确保您使用的服务账号至少具有 Service Account Token Creator (
roles/iam.serviceAccountTokenCreator
) 角色。创建并部署接受用户登录凭据的服务器端点。
使用 Admin SDK 创建自定义令牌
Admin SDK 内置了创建自定义令牌的方法。您至少需要提供 uid
。它可以是唯一标识用户或设备的任意字符串。这些令牌会在 1 小时后过期。
以下示例展示了如何创建自定义令牌:
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
在您创建自定义令牌之后,您的应用可以使用该令牌来登录用户。
您也可以选择在自定义令牌中添加其他声明。这些声明将被作为顶级声明传播到用户的 ID 令牌。
以下示例展示了如何添加 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 符合 OpenID Connect JWT 规范。这意味着以下声明已由系统保留,您无法指定:
acr
amr
at_hash
aud
auth_time
azp
cnf
c_hash
exp
firebase
iat
iss
jti
nbf
nonce
sub
使用第三方 JWT 库创建自定义令牌
如果您的后端是使用 Admin SDK 不支持的语言编写的,您仍然可以手动创建自定义令牌。首先,找到适合您的语言的第三方 JWT 库。然后,使用该库创建一个包含以下声明的 JWT:
alg |
算法 | "RS256" |
iss |
颁发者 | 您项目的服务账号电子邮件地址。 |
sub |
主题 | 您项目的服务账号电子邮件地址。 |
aud |
受众 | "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit" |
iat |
颁发时间 | 当前时间(与 UNIX 计时原点之间相隔的秒数) |
exp |
到期时间 |
令牌到期的时间(与 UNIX 计时原点之间相隔的秒数),该时间可能比 iat 晚最多 3600 秒。
请注意,这仅会控制自定义令牌本身的过期时间。一旦您使用 signInWithCustomToken() 让用户登录,他们将一直保持登录状态,直到其退出账号或会话失效。 |
uid |
已登录用户的唯一标识符。必须是长度为 1-36 个字符的字符串。 | |
claims (可选) |
需要包含的其他自定义声明。 |
以下示例展示了如何使用 Admin SDK 不支持的语言创建自定义令牌:
PHP
使用 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
使用 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
在您创建自定义令牌之后,您的应用可以使用该令牌来登录用户。
后续步骤
- 让用户通过自定义令牌登录。
- 为用户配置自定义声明。
- 使用 REST API 将 Identity Platform 与自定义身份验证系统的其他部分集成。