JWT 声明参考
Complete reference for claims appearing in JWTs created by Supabase Auth
本页面提供了 Supabase 认证令牌中使用的所有 JWT 声明的全面参考。这些信息对于服务器端的 JWT 验证和序列化非常重要,特别是在像 Rust 这样的语言中实现认证时,因为 ref 这样的字段名是保留关键字。
🌐 This page provides a comprehensive reference for all JWT claims used in Supabase authentication tokens. This information is essential for server-side JWT validation and serialization, especially when implementing authentication in languages like Rust where field names like ref are reserved keywords.
JWT 结构概览 #
🌐 JWT structure overview
Supabase 的 JWT 遵循标准的 JWT 结构,分为三个部分:
🌐 Supabase JWTs follow the standard JWT structure with three parts:
- 标题:包含算法和关键信息
- 有效载荷:包含声明(用户数据和元数据)
- 签名:用于验证的加密签名
这个有效载荷包含各种声明,用来提供用户身份、认证级别和授权信息。
🌐 The payload contains various claims that provide user identity, authentication level, and authorization information.
必需的索赔 #
🌐 Required claims
这些声明总是存在于 Supabase 的 JWT 中,无法删除:
🌐 These claims are always present in Supabase JWTs and cannot be removed:
| 字段 | 类型 | 描述 | 示例 |
|---|---|---|---|
iss | string | 发行者 - 签发 JWT 的实体 | "https://project-ref.supabase.co/auth/v1" |
aud | string | string[] | 受众 - JWT 的预期接收者 | "authenticated" 或 "anon" |
exp | number | 过期时间 - 令牌过期的 Unix 时间戳 | 1640995200 |
iat | number | 签发时间 - token 被签发时的 Unix 时间戳 | 1640991600 |
sub | string | 主题 - 用户 ID (UUID) | "123e4567-e89b-12d3-a456-426614174000" |
role | string | 角色 - 用户在系统中的角色 | "authenticated"、"anon"、"service_role" |
aal | string | 认证保证级别 - 认证强度 | "aal1", "aal2" |
session_id | string | 会话 ID - 唯一的会话标识符 | "session-uuid" |
email | string | 电子邮件 - 用户的电子邮箱地址 | "user@example.com" |
phone | string | 电话 - 用户的电话号码 | "+1234567890" |
is_anonymous | boolean | 匿名标志 - 用户是否匿名 | false |
可选声明 #
🌐 Optional claims
这些声明可能会根据身份验证的上下文而存在:
🌐 These claims may be present depending on the authentication context:
| 字段 | 类型 | 描述 | 示例 |
|---|---|---|---|
jti | string | JWT ID - JWT 的唯一标识符 | "jwt-uuid" |
nbf | number | Not Before - 在此 Unix 时间戳之前令牌无效 | 1640991600 |
app_metadata | object | 应用元数据 - 特定应用的用户数据 | {"provider": "email"} |
user_metadata | object | 用户元数据 - 用户特定数据 | {"name": "John Doe"} |
amr | array | 认证方法参考 - 使用的认证方法列表 | [{"method": "password", "timestamp": 1640991600}] |
特殊要求 #
🌐 Special claims
| 字段 | 类型 | 描述 | 示例 | 使用场景 |
|---|---|---|---|---|
ref | string | 项目引用 - Supabase 项目标识符 | "abcdefghijklmnopqrst" | 仅限匿名/服务角色令牌 |
字段值限制 #
🌐 Field value constraints
身份验证器保障级别(aal#
🌐 Authenticator assurance level (aal)
| 值 | 描述 |
|---|---|
"aal1" | 单因素认证(密码、OAuth 等) |
"aal2" | 多因素认证(密码 + TOTP 等) |
角色值 (role#
🌐 Role values (role)
| 值 | 描述 | 使用场景 |
|---|---|---|
"anon" | 匿名用户 | 带 RLS 策略的公共访问 |
"authenticated" | 已认证用户 | 标准用户访问 |
"service_role" | 服务角色 | 管理员权限(仅限服务器端) |
受众价值(aud#
🌐 Audience values (aud)
| 值 | 描述 |
|---|---|
"authenticated" | 用于已认证用户的令牌 |
"anon" | 用于匿名用户的令牌 |
认证方法(amr.method#
🌐 Authentication methods (amr.method)
| 值 | 描述 |
|---|---|
"oauth" | OAuth 提供商认证 |
"password" | 邮箱/密码认证 |
"otp" | 一次性密码 |
"totp" | 基于时间的一次性密码 |
"recovery" | 账户恢复 |
"invite" | 邀请注册 |
"sso/saml" | SAML 单点登录 |
"magiclink" | 魔法链接认证 |
"email/signup" | 邮箱注册 |
"email_change" | 邮箱更换 |
"token_refresh" | 令牌刷新 |
"anonymous" | 匿名认证 |
JWT 示例 #
🌐 JWT examples
已认证用户令牌 #
🌐 Authenticated user token
{ "aal": "aal1", "amr": [ { "method": "password", "timestamp": 1640991600 } ], "app_metadata": { "provider": "email", "providers": ["email"] }, "aud": "authenticated", "email": "user@example.com", "exp": 1640995200, "iat": 1640991600, "iss": "https://abcdefghijklmnopqrst.supabase.co/auth/v1", "phone": "", "role": "authenticated", "session_id": "123e4567-e89b-12d3-a456-426614174000", "sub": "123e4567-e89b-12d3-a456-426614174000", "user_metadata": { "name": "John Doe" }, "is_anonymous": false}匿名用户令牌 #
🌐 Anonymous user token
{ "iss": "supabase", "ref": "abcdefghijklmnopqrst", "role": "anon", "iat": 1640991600, "exp": 1640995200}服务角色令牌 #
🌐 Service role token
{ "iss": "supabase", "ref": "abcdefghijklmnopqrst", "role": "service_role", "iat": 1640991600, "exp": 1640995200}语言特定的考虑 #
🌐 Language-Specific considerations
Rust#
在 Rust 中,ref 字段是一个保留关键字。反序列化 JWT 时,你需要这样处理:
🌐 In Rust, the ref field is a reserved keyword. When deserializing JWTs, you'll need to handle this:
use serde::{Deserialize, Serialize};#[derive(Debug, Deserialize, Serialize)]struct JwtClaims { iss: String, #[serde(rename = "ref")] // Handle reserved keyword project_ref: Option<String>, role: String, iat: i64, exp: i64, // ... other claims}TypeScript/JavaScript#
interface { : string : string | string[] : number : number : string : string : 'aal1' | 'aal2' : string : string : string : boolean ?: string ?: number ?: <string, any> ?: <string, any> ?: <{ : string : number }> ?: string // Only in anon/service role tokens}Python#
from typing import Optional, Union, List, Dict, Anyfrom dataclasses import dataclass@dataclassclass AmrEntry: method: str timestamp: int@dataclassclass JwtClaims: iss: str aud: Union[str, List[str]] exp: int iat: int sub: str role: str aal: str session_id: str email: str phone: str is_anonymous: bool jti: Optional[str] = None nbf: Optional[int] = None app_metadata: Optional[Dict[str, Any]] = None user_metadata: Optional[Dict[str, Any]] = None amr: Optional[List[AmrEntry]] = None ref: Optional[str] = None # Only in anon/service role tokens去 #
🌐 Go
type AmrEntry struct { Method string `json:"method"` Timestamp int64 `json:"timestamp"`}type JwtClaims struct { Iss string `json:"iss"` Aud interface{} `json:"aud"` // string or []string Exp int64 `json:"exp"` Iat int64 `json:"iat"` Sub string `json:"sub"` Role string `json:"role"` Aal string `json:"aal"` SessionID string `json:"session_id"` Email string `json:"email"` Phone string `json:"phone"` IsAnonymous bool `json:"is_anonymous"` Jti *string `json:"jti,omitempty"` Nbf *int64 `json:"nbf,omitempty"` AppMetadata map[string]interface{} `json:"app_metadata,omitempty"` UserMetadata map[string]interface{} `json:"user_metadata,omitempty"` Amr []AmrEntry `json:"amr,omitempty"` Ref *string `json:"ref,omitempty"` // Only in anon/service role tokens}验证指南 #
🌐 Validation guidelines
在你的服务器上实现 JWT 验证时:
🌐 When implementing JWT validation on your server:
- 检查必填字段:确保所有必填项都已填写
- 验证类型:确认字段类型是否与预期类型匹配
- 检查过期:确认
exp时间戳是在将来 - 验证发行者:确保
iss与你的 Supabase 项目匹配 - 检查受众:确认
aud是否符合预期受众 - 处理保留关键字:在 Rust 等语言中使用字段重命名
安全注意事项 #
🌐 Security considerations
- 在信任任何声明之前,一定要验证 JWT 签名
- 绝不要将服务角色令牌暴露给客户端代码
- 在信任 JWT 之前先验证所有声明
- 在每次请求时检查令牌过期情况
- 在传输所有 JWT 时使用 HTTPS
- 定期更换 JWT 密钥
- 为无效的令牌 实现适当的错误处理
相关文档 #
🌐 Related documentation