You need to enable JavaScript to run this app.
文档中心
AI 原生 BaaS 平台 Supabase 版

AI 原生 BaaS 平台 Supabase 版

复制全文
下载 pdf
使用 Authentication
设置 Auth Hooks
复制全文
下载 pdf
设置 Auth Hooks
Auth Hooks(认证钩子)是 Supabase Auth 提供的扩展机制,允许您在用户认证流程的关键节点(如用户创建前后、登录前后、发送邮件/短信前后等)插入自定义逻辑,实现诸如邮箱白名单校验、自定义 Token 声明、异步事件通知等业务能力。​
本文介绍如何在 Supabase 控制台或通过 Admin API 为应用配置 Auth Hooks。当前共支持 8 种 Hook 类型,并支持以下增强能力:​
  • 传递 JWT Token:HTTPS Hook 可携带用户 JWT,便于回调端做身份校验。​
  • 异步聚合:HTTPS Hook 可按数量或时长阈值聚合后批量触发,降低对回调端的压力。​
相关概念​
详细原理与设计可参考 Supabase 官方文档 Supabase Auth Hooks。​
典型使用场景​
🛡️ 注册前置校验​
通过 Before User Created Hook 校验用户邮箱、手机号是否符合业务规则(如限制公司邮箱、过滤黑名单等),不合规则阻断注册。​
🔐 自定义 JWT Claims​
通过 Custom Access Token Hook 在颁发 JWT 时注入业务自定义的 Claims(如租户 ID、角色信息),扩展 JWT 的业务语义。​
​
📨 自定义短信/邮件模板​
通过 Send SMS / Send Email Hook 接管 OTP 等通知的发送逻辑,对接企业内部短信网关或邮件服务。​
📊 异步事件通知​
通过 After User Created / Signed In / SMS Sent Hook 异步接收认证事件,便于做用户画像、风控、数据分析等下游处理。​
​
前提条件​
  • 已创建使用 Supabase 引擎的 Workspace,且该 Workspace 处于运行中状态。详细操作请参见创建 Workspace。​
  • 已获取 SUPABASE_BASE_URL、SERVICE_ROLE_KEY 和 SUPABASE_ANON_KEY。关于获取变量的详细信息,请参见获取变量。​
通过 Supabase 控制台查询和修改配置​
  1. 在 Supabase 控制台左侧导航栏单击 Authentication,进入 Authentication 页面。​
  1. 在 Authentication 页面,单击 Auth Hooks 标签页。​
  1. 添加或编辑 Hook:​
  • 单击 Add hook 下拉按钮,选择需要的 Hook 类型,进行配置。​
  • 或单击已有 Hook 的 Configure hook 按钮,修改其配置。​
  1. 在弹出的配置页面,根据需要选择 Hook 模式(Postgres 或 HTTPS),并完成参数配置:​
  • Postgres 模式:选择 Postgres Schema 和 Postgres Function,并填写相关 Statements。Hook 触发时将调用该 Postgres Function。​
  • HTTPS 模式:​
  1. 填写 URL(回调地址)和 Secret(用于校验请求合法性)。​
  1. (可选)开启 Include JWT in Header,向回调端传递用户 JWT Token;开启后需配置 JWT Time-to-Live(默认 300 秒)。​
  1. (可选)开启 Enable aggregation,启用异步聚合;开启后需配置 Aggregation Count Threshold(累计调用次数阈值)和 Aggregation Duration Threshold(累计时长阈值)。​
支持的 Hook 列表​
​
Hook 显示名称​
HOOKNAME 枚举值​
触发时机​
是否阻塞用户交互​
是否支持 PostgreSQL Function 模式​
是否支持 HTTPS 模式​
是否支持传递用户的 JWT Token​
是否支持异步聚合​
Before User Created​
BEFORE_USER_CREATED​
是​
是​
是​
是​
否​
Custom Access Token​
CUSTOM_ACCESS_TOKEN​
是​
是​
是​
是​
否​
Send SMS​
SEND_SMS​
是​
是​
是​
是​
否​
Send Email​
SEND_EMAIL​
是​
是​
是​
是​
否​
Password Verification Attempt​
PASSWORD_VERIFICATION_ATTEMPT​
是​
是​
是​
是​
否​
After User Created​
AFTER_USER_CREATED​
在用户注册成功后触发​
否​
是​
是​
是​
是​
After User Signed In​
AFTER_USER_SIGNED​
在用户登录成功后触发​
否​
是​
是​
是​
是​
After SMS Sent​
AFTER_SMS_SENT​
在向用户发送短信成功后触发​
否​
是​
是​
是​
是​
​
主要配置项说明​
主要配置项如下。其中 ${HOOKNAME} 为占位符,需要替换为上节表格中的 “HOOKNAME 枚举值”。​
​
Dashboard 配置项名称​
配置项 Key​
配置项 Value 类型​
是否必填​
配置项说明​
Enable hook​
HOOK_${HOOKNAME}_ENABLED​
bool​
否​
​
是否启用该 Hook。取值:​
  • true:是(开关打开)。​
  • false:否(开关关闭)。​
URL​
HOOK_${HOOKNAME}_URI​
string​
否​
HTTPS 模式下的回调 URL。当 Hook 为HTTPS 模式时为必填。​
Secret​
​
HOOK_${HOOKNAME}_SECRETS​
string​
否​
HTTPS 模式下,携带的 Websocket Secret:​
  • 默认值为空串。​
  • 自定义值的格式必须满足以下两个正则表达式之一:​
  • ^v1,whsec_[A-Za-z0-9+/=]{32,88}​
  • ^v1a,whpk_[A-Za-z0-9+/=]{44,}:whsk_[A-Za-z0-9+/=]{44,}$​
Include JWT in Header​
HOOK_${HOOKNAME}_ENABLE_JWT​
bool​
否​
HTTPS 模式下,是否需要传递用户的 JWT Token,取值如下:​
  • true:是。​
  • false:否 (默认值)。​
JWT Time-to-Live (TTL)​
HOOK_${HOOKNAME}_JWT_TTL​
int​
否​
HTTPS 模式下,传递的用户的 JWT Token 的有效期,单位为秒。​
  • 取值范围为 [1,900]。​
  • 默认值为 300。​
Enable aggregation​
​
​
HOOK_${HOOKNAME}_ENABLE_AGGREGATE​
bool​
否​
是否开启异步聚合。取值:​
  • true:是。​
  • false:否 (默认值)。​
Aggregation Count Threshold​
HOOK_${HOOKNAME}_AGGR_COUNT_THRESHOLD​
int​
否​
HTTPS 模式下,异步聚合的个数阈值:​
  • 取值范围为 [2, 10000]。​
  • 默认值为 100。​
  • 本参数可以与HOOK_${HOOKNAME}_AGGR_DURATION_THRESHOLD 同时设置。如果满足这两个阈值之一,则触发 Hook,并重置计数和计时。​
Aggregation Duration Threshold​
HOOK_${HOOKNAME}_AGGR_DURATION_THRESHOLD​
int​
否​
HTTPS 模式下,异步聚合的时长阈值。单位为秒。​
  • 取值范围为 [60,43200]。​
  • 默认值为 300。​
  • 本参数可以与HOOK_${HOOKNAME}_AGGR_COUNT_THRESHOLD 同时设置。如果满足这两个阈值之一,则触发 Hook,并重置计数和计时。​
​
通过 Admin API 查询和修改配置​
您也可以通过 Auth 模块的 Admin API /auth/v1/config/hooks 接口查询和修改 Hook 配置,便于自动化部署或集成到 CI/CD 流程。​
  • 查询配置的示例​
​
curl -X GET $SUPABASE_BASE_URL/auth/v1/config/hooks \​
-H "apikey: ${SERVICE_ROLE_KEY}" \​
-H "Authorization: Bearer ${SERVICE_ROLE_KEY}" \​
-H "Content-Type: application/json"​
​
  • 修改配置的示例,其中 body 为上节表格中的 配置项 Key 和 配置项 Value 组成的 JSON Map​
​
curl -X PATCH $SUPABASE_BASE_URL/auth/v1/config/hooks \​
-H "apikey: ${SERVICE_ROLE_KEY}" \​
-H "Authorization: Bearer ${SERVICE_ROLE_KEY}" \​
-H "Content-Type: application/json" \​
-d '{​
"HOOK_AFTER_USER_CREATED_ENABLED": true,​
"HOOK_AFTER_USER_CREATED_URI": "https://$SUPABASE_BASE_URL/functions/v1/after-user-created",​
"HOOK_AFTER_USER_CREATED_SECRETS": "v1,whsec_test",​
"HOOK_AFTER_USER_CREATED_ENABLE_JWT": true,​
"HOOK_AFTER_USER_CREATED_JWT_TTL": 900,​
"HOOK_AFTER_USER_CREATED_ENABLE_AGGREGATE": true,​
"HOOK_AFTER_USER_CREATED_AGGR_COUNT_THRESHOLD": 1,​
"HOOK_AFTER_USER_CREATED_AGGR_DURATION_THRESHOLD": 0,​
...​
}'​
​
Hook实现示例​
以下示例介绍 Hook 回调端的输入/输出契约和参考实现。各 Hook 类型的 Payload 结构定义可进一步参考 Supabase Auth Hooks 官方文档。​
未开启异步聚合类型的HTTPS Hook示例​
以 Before User Created Hook 为例,HTTPS Endpoint 可编写为一个 Edge Function(实现公司邮箱白名单校验):​
​
Deno.serve(async (req) => {​
if (req.method !== "POST") {​
return new Response("Method Not Allowed", { status: 405 })​
}​
​
let payload: any​
try {​
payload = await req.json()​
} catch {​
return new Response(​
JSON.stringify({​
error: { http_code: 400, message: "Invalid JSON" }​
}),​
{ status: 400, headers: { "Content-Type": "application/json" } }​
)​
}​
​
const email = payload?.user?.email ?? ""​
if (!email.endsWith("@bytedance.com")) {​
return new Response(​
JSON.stringify({​
error: { http_code: 400, message: "仅限公司邮箱注册。" }​
}),​
{ status: 200, headers: { "Content-Type": "application/json" } }​
)​
}​
​
return new Response(JSON.stringify(payload), {​
status: 200,​
headers: { "Content-Type": "application/json" }​
})​
})​
​
  • 输入JSON示例​
​
{​
"metadata": {​
"uuid": "1ac7639b-68fe-49be-af48-c3573168a950",​
"request_id": "20260327171750D1EAB27246339F4E5354",​
"time": "2026-03-30T09:35:07.008836097Z",​
"name": "before-user-created",​
"ip_address": "113.200.149.26",​
"workspace_id": "ws_xxx",​
"branch_id": "br_xxx"​
},​
"user": {​
"id": "5d3a681c-a031-41fb-8b57-55ea5d2337ab",​
"aud": "authenticated",​
"role": "",​
"email": "alex@bytedance.com",​
"phone": "",​
"app_metadata": {​
"provider": "email",​
"providers": [​
"email"​
]​
},​
"user_metadata": {},​
"identities": [],​
"created_at": "0001-01-01T00:00:00Z",​
"updated_at": "0001-01-01T00:00:00Z",​
"is_anonymous": false​
},​
​
"user_id": "5d3a681c-a031-41fb-8b57-55ea5d2337ab",​
​
"aggr_count": 1,​
"aggr_start_time": "2026-03-30T09:35:07.008836097Z",​
"aggr_end_time": "2026-03-30T09:35:07.008836097Z"​
}​
​
  • 输出要求​
​
Hook 结果​
HTTP Response Code​
HTTP Response Body​
示例​
成功​
​
200​
  1. 对于 “Custom Access Token” Hook,需要返回包含 claims 结构体的 JSON 串;具体参考 用于自定义用户的 Access Token(JWT)​
  1. 对于其他 Hook,可返回空的 JSON 串​
  1. “Custom Access Token” Hook 的 Response 示例​
​
return new Response(​
JSON.stringify({​
claims,​
}),​
{ status: 200, headers: { 'Content-Type': 'application/json'} }​
)​
​
  1. 其他 Hook 的 Response 示例​
​
return new Response(​
JSON.stringify({}),​
{ status: 200, headers: { "Content-Type": "application/json" } }​
)​
​
失败​
非 200​
包含错误信息的 JSON 串​
​
return new Response(​
JSON.stringify({​
error: { ​
http_code: 400, ​
message: "Please sign up with a company email address.'" ​
},​
}),​
{ status: 400, headers: { "Content-Type": "application/json" } }​
)​
​
​
已开启异步聚合类的HTTPS Hook示例​
  • 输入 JSON 示例​
​
{​
"metadata": {​
"uuid": "1ac7639b-68fe-49be-af48-c3573168a950",​
"request_id": "20260327171750D1EAB27246339F4E5354",​
"time": "2026-03-30T09:35:07.008836097Z",​
"name": "before-user-created",​
"ip_address": "113.200.149.26",​
"workspace_id": "ws_xxx",​
"branch_id": "br_xxx"​
},​
"user": {},​
"user_id": "",​
​
"aggr_count": 3,​
"aggr_start_time": "2026-03-30T09:34:07.008836097Z",​
"aggr_end_time": "2026-03-30T09:36:27.008836097Z"​
}​
​
  • 输出要求:与非异步聚合的输出要求一致​
PostgreSQL Function的示例​
仍然以 BEFORE_USER_CREATED 为例,PostgreSQL Hook Function 编写如下:​
​
Deno.serve(async (req) => {​
if (req.method !== "POST") {​
return new Response("Method Not Allowed", { status: 405 })​
}​
​
let payload: any​
try {​
payload = await req.json()​
} catch {​
return new Response(​
JSON.stringify({​
error: { ​
http_code: 400, ​
message: "Invalid JSON" ​
},​
}),​
{ status: 400, headers: { "Content-Type": "application/json" } }​
)​
}​
​
const email = payload?.user?.email ?? ""​
if (!email.endsWith("@example.com")) {​
return new Response(​
JSON.stringify({​
error: { ​
http_code: 400, ​
message: "Please sign up with a company email address.'" ​
},​
}),​
{ status: 200, headers: { "Content-Type": "application/json" } }​
)​
}​
​
return new Response(JSON.stringify(payload), {​
status: 200,​
headers: { "Content-Type": "application/json" }​
})​
})​
​
超时与重试机制​
重要​
Hook 调用存在超时与重试限制,请确保回调端能在规定时间内响应,避免影响用户认证流程。​
不同 Hook 模式的超时与重试规则如下:​
​
Hook 模式​
单次执行超时​
失败重试策略​
整体超时​
PostgreSQL Function​
3 秒​
失败/超时间隔 2 秒重试,最多 3 次(含首次)​
—​
HTTPS(未开启异步聚合)​
8 秒​
失败/超时间隔 2 秒重试,最多 3 次(含首次)​
阻塞型 Hook:30 秒;非阻塞型 Hook:1 分钟​
HTTPS(已开启异步聚合)​
15 秒​
失败/超时间隔 2 秒重试,最多 3 次(含首次)​
阻塞型 Hook:30 秒;非阻塞型 Hook:1 分钟​
​
说明​
超过重试上限后,系统将不再继续重试,仅记录错误日志。Hook 是否阻塞用户交互可参考上文「支持的 Hook 列表」中的「是否阻塞用户交互字段。​
最近更新时间:2026.06.16 16:40:46
这个页面对您有帮助吗?
有用
有用
无用
无用