Skip to content
Auth

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:

字段类型描述示例
issstring发行者 - 签发 JWT 的实体"https://project-ref.supabase.co/auth/v1"
audstring | string[]受众 - JWT 的预期接收者"authenticated""anon"
expnumber过期时间 - 令牌过期的 Unix 时间戳1640995200
iatnumber签发时间 - token 被签发时的 Unix 时间戳1640991600
substring主题 - 用户 ID (UUID)"123e4567-e89b-12d3-a456-426614174000"
rolestring角色 - 用户在系统中的角色"authenticated""anon""service_role"
aalstring认证保证级别 - 认证强度"aal1", "aal2"
session_idstring会话 ID - 唯一的会话标识符"session-uuid"
emailstring电子邮件 - 用户的电子邮箱地址"user@example.com"
phonestring电话 - 用户的电话号码"+1234567890"
is_anonymousboolean匿名标志 - 用户是否匿名false

可选声明 #

🌐 Optional claims

这些声明可能会根据身份验证的上下文而存在:

🌐 These claims may be present depending on the authentication context:

字段类型描述示例
jtistringJWT ID - JWT 的唯一标识符"jwt-uuid"
nbfnumberNot Before - 在此 Unix 时间戳之前令牌无效1640991600
app_metadataobject应用元数据 - 特定应用的用户数据{"provider": "email"}
user_metadataobject用户元数据 - 用户特定数据{"name": "John Doe"}
amrarray认证方法参考 - 使用的认证方法列表[{"method": "password", "timestamp": 1640991600}]

特殊要求 #

🌐 Special claims

字段类型描述示例使用场景
refstring项目引用 - 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

1
{
2
"aal": "aal1",
3
"amr": [
4
{
5
"method": "password",
6
"timestamp": 1640991600
7
}
8
],
9
"app_metadata": {
10
"provider": "email",
11
"providers": ["email"]
12
},
13
"aud": "authenticated",
14
"email": "user@example.com",
15
"exp": 1640995200,
16
"iat": 1640991600,
17
"iss": "https://abcdefghijklmnopqrst.supabase.co/auth/v1",
18
"phone": "",
19
"role": "authenticated",
20
"session_id": "123e4567-e89b-12d3-a456-426614174000",
21
"sub": "123e4567-e89b-12d3-a456-426614174000",
22
"user_metadata": {
23
"name": "John Doe"
24
},
25
"is_anonymous": false
26
}

匿名用户令牌 #

🌐 Anonymous user token

1
{
2
"iss": "supabase",
3
"ref": "abcdefghijklmnopqrst",
4
"role": "anon",
5
"iat": 1640991600,
6
"exp": 1640995200
7
}

服务角色令牌 #

🌐 Service role token

1
{
2
"iss": "supabase",
3
"ref": "abcdefghijklmnopqrst",
4
"role": "service_role",
5
"iat": 1640991600,
6
"exp": 1640995200
7
}

语言特定的考虑 #

🌐 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:

1
use serde::{Deserialize, Serialize};
2
3
#[derive(Debug, Deserialize, Serialize)]
4
struct JwtClaims {
5
iss: String,
6
#[serde(rename = "ref")] // Handle reserved keyword
7
project_ref: Option<String>,
8
role: String,
9
iat: i64,
10
exp: i64,
11
// ... other claims
12
}

TypeScript/JavaScript#

1
interface JwtClaims {
2
iss: string
3
aud: string | string[]
4
exp: number
5
iat: number
6
sub: string
7
role: string
8
aal: 'aal1' | 'aal2'
9
session_id: string
10
email: string
11
phone: string
12
is_anonymous: boolean
13
jti?: string
14
nbf?: number
15
app_metadata?: Record<string, any>
16
user_metadata?: Record<string, any>
17
amr?: Array<{
18
method: string
19
timestamp: number
20
}>
21
ref?: string // Only in anon/service role tokens
22
}

Python#

1
from typing import Optional, Union, List, Dict, Any
2
from dataclasses import dataclass
3
4
@dataclass
5
class AmrEntry:
6
method: str
7
timestamp: int
8
9
@dataclass
10
class JwtClaims:
11
iss: str
12
aud: Union[str, List[str]]
13
exp: int
14
iat: int
15
sub: str
16
role: str
17
aal: str
18
session_id: str
19
email: str
20
phone: str
21
is_anonymous: bool
22
jti: Optional[str] = None
23
nbf: Optional[int] = None
24
app_metadata: Optional[Dict[str, Any]] = None
25
user_metadata: Optional[Dict[str, Any]] = None
26
amr: Optional[List[AmrEntry]] = None
27
ref: Optional[str] = None # Only in anon/service role tokens

#

🌐 Go

1
type AmrEntry struct {
2
Method string `json:"method"`
3
Timestamp int64 `json:"timestamp"`
4
}
5
6
type JwtClaims struct {
7
Iss string `json:"iss"`
8
Aud interface{} `json:"aud"` // string or []string
9
Exp int64 `json:"exp"`
10
Iat int64 `json:"iat"`
11
Sub string `json:"sub"`
12
Role string `json:"role"`
13
Aal string `json:"aal"`
14
SessionID string `json:"session_id"`
15
Email string `json:"email"`
16
Phone string `json:"phone"`
17
IsAnonymous bool `json:"is_anonymous"`
18
Jti *string `json:"jti,omitempty"`
19
Nbf *int64 `json:"nbf,omitempty"`
20
AppMetadata map[string]interface{} `json:"app_metadata,omitempty"`
21
UserMetadata map[string]interface{} `json:"user_metadata,omitempty"`
22
Amr []AmrEntry `json:"amr,omitempty"`
23
Ref *string `json:"ref,omitempty"` // Only in anon/service role tokens
24
}

验证指南 #

🌐 Validation guidelines

在你的服务器上实现 JWT 验证时:

🌐 When implementing JWT validation on your server:

  1. 检查必填字段:确保所有必填项都已填写
  2. 验证类型:确认字段类型是否与预期类型匹配
  3. 检查过期:确认 exp 时间戳是在将来
  4. 验证发行者:确保 iss 与你的 Supabase 项目匹配
  5. 检查受众:确认 aud 是否符合预期受众
  6. 处理保留关键字:在 Rust 等语言中使用字段重命名

安全注意事项 #

🌐 Security considerations

  • 在信任任何声明之前,一定要验证 JWT 签名
  • 绝不要将服务角色令牌暴露给客户端代码
  • 在信任 JWT 之前先验证所有声明
  • 在每次请求时检查令牌过期情况
  • 在传输所有 JWT 时使用 HTTPS
  • 定期更换 JWT 密钥
  • 为无效的令牌 实现适当的错误处理

🌐 Related documentation