认证钩子
使用HTTP或Postgres函数自定义您的认证流程
什么是钩子
钩子是一种端点,允许您在 Supabase Auth 流程的特定执行点修改默认行为。开发者可以使用钩子添加原生不支持的自定义功能。
钩子能帮助您:
- 通过添加元数据追踪用户注册来源
- 通过为密码和多因素认证添加额外检查来提升安全性
- 通过集成外部认证系统的身份凭证来支持遗留系统
- 向 JWT 添加额外的自定义声明
- 通过自定义提供商发送认证邮件或短信
当前可用的钩子包括:
钩子 | 适用计划 |
---|---|
自定义访问令牌 | 免费版、专业版 |
发送短信 | 免费版、专业版 |
发送邮件 | 免费版、专业版 |
MFA验证尝试 | 团队版和企业版 |
密码验证尝试 | 团队版和企业版 |
Supabase 支持两种方式在项目中配置钩子:
可以将 Postgres 函数配置为钩子。该函数应接收单个参数——JSONB 类型的事件——并返回一个 JSONB 对象。由于 Postgres 函数在您的数据库上运行,请求不会离开项目实例。
安全模型
通过签名负载和选择性授权来保障负载的完整性。
当您将Postgres函数配置为钩子时,Supabase会自动为函数应用以下授权,原因如下:
- 允许
supabase_auth_admin
角色执行该函数。supabase_auth_admin
角色是Supabase Auth用于向数据库发起请求的Postgres角色。 - 撤销其他角色(如
anon
、authenticated
、public
)的权限,确保Supabase数据API无法访问该函数。
123456789101112-- 授予supabase_auth_admin执行函数的权限grant execute on function public.custom_access_token_hook to supabase_auth_admin;-- 授予supabase_auth_admin使用schema的权限grant usage on schema public to supabase_auth_admin;-- 撤销authenticated、anon和public角色的函数权限revoke execute on function public.custom_access_token_hook from authenticated, anon, public;
您需要修改行级安全(RLS)策略,允许supabase_auth_admin
角色访问您设置了RLS策略的表。了解更多关于RLS策略的内容请参阅此处。
或者,您可以通过仪表板创建带有security definer
标签的Postgres函数。security definer
标签指定函数将以函数所有者的权限执行。
目前,通过仪表板创建的函数会继承postgres
角色。了解更多关于security definer
标签的内容请参阅我们的数据库指南
使用钩子(Hooks)
开发指南
让我们先在本地开发一个Hook,然后将其部署到云端。以下是可用Hook的概述:
Hook | 建议的函数名 | 触发时机 | 功能描述 |
---|---|---|---|
发送短信 | send_sms | 每次发送短信时 | 允许自定义消息内容和短信服务提供商 |
发送邮件 | send_email | 每次发送邮件时 | 允许自定义邮件内容和邮件服务提供商 |
自定义访问令牌 | custom_access_token | 每次创建新JWT时 | 返回您希望在JWT中包含的声明 |
MFA验证尝试 | mfa_verification_attempt | 用户尝试验证MFA因素时 | 返回是否拒绝该尝试及后续尝试,或允许用户继续尝试的决定 |
密码验证尝试 | password_verification_attempt | 用户尝试用密码登录时 | 返回是否拒绝该尝试或允许用户继续尝试的决定 |
编辑config.toml
以在本地设置Auth Hook。
修改auth.hook.<hook_name>
字段,将uri
设置为pg-functions://postgres/<schema>/<function_name>
123[auth.hook.<hook_name>]enabled = trueuri = "pg-functions://...."
需要分配额外权限,使Supabase Auth可以访问Hook及其交互的表。
supabase_auth_admin
角色没有public
模式的权限。需要授予该角色执行Hook的权限:
123grant execute on function public.custom_access_token_hook to supabase_auth_admin;
还需要授予supabase_auth_admin
使用权限:
1grant usage on schema public to supabase_auth_admin;
同时撤销authenticated
和anon
角色的权限,确保函数无法通过Supabase无服务器API访问。
123revoke execute on function public.custom_access_token_hook from authenticated, anon;
出于安全考虑,我们不建议使用security definer
标签。该标签指定函数以所有者权限执行。通过Supabase仪表板创建的函数若带有该标签,将拥有postgres
角色的广泛权限,可能导致不良操作。
建议不使用任何标签,而是按照上述方式明确授予supabase_auth_admin
权限。
更多关于security definer
标签的信息,请参阅数据库指南。
完成后,将Auth Hook保存为迁移文件以便版本控制和团队共享。运行supabase migration new
创建迁移。
如果使用Supabase SQL编辑器,在使用?
操作符(字符串是否作为顶级键存在于JSON值中?)时存在问题。定义函数时如需使用该操作符,请直接连接数据库。
以下是Hook签名示例:
1234567891011create or replace function public.custom_access_token_hook(event jsonb)returns jsonblanguage plpgsqlas $$declare -- 在此声明变量begin -- 在此添加逻辑 return event;end;$$;
可访问SQL编辑器 > 模板
获取Hook模板。
部署
在仪表盘中,导航至 认证 > 钩子
并从下拉菜单中选择适当的函数类型(SQL 或 HTTP)。
错误处理
当遇到运行时错误时,您应该返回一个错误。运行时错误特定于您的应用程序,源于特定的业务规则而非程序员错误。
运行时错误可能发生在以下情况:
- 用户没有适当的权限
- 接收到的事件负载缺少必需的声明
- 用户执行了违反业务规则的操作
- 在webhook中使用的电子邮件或电话提供商返回了错误
错误是一个JSON对象,具有以下属性:
error
包含错误信息的对象http_code
表示要返回的HTTP状态码的数字。如果未设置,则默认为HTTP 500内部服务器错误message
要在HTTP响应中返回的消息(必需)
示例:
123456{ "error": { "http_code": 429, "message": "每个验证因子每10秒只能验证一次。" }}
从Postgres Hook返回的错误不可重试。当返回错误时,错误会从hook传播到Supabase Auth,并转换为HTTP错误返回给您的应用程序。Supabase Auth只会考虑错误信息,而忽略负载的其他部分。
除了运行时错误外,HTTP Hook和Postgres Hook都会返回超时错误。Postgres Hook必须在2秒内完成处理,而HTTP Hook应在5秒内完成。两种Hook都在事务中运行,以限制执行时间,避免认证过程延迟。
可用钩子
每个钩子描述都包含一个示例JSON Schema,您可以结合使用JSON Schema Faker来生成模拟负载。对于HTTP钩子,您还可以使用标准Webhooks测试工具来模拟请求。