认证

认证钩子

使用HTTP或Postgres函数自定义您的认证流程


什么是钩子

钩子是一种端点,允许您在 Supabase Auth 流程的特定执行点修改默认行为。开发者可以使用钩子添加原生不支持的自定义功能。

钩子能帮助您:

  • 通过添加元数据追踪用户注册来源
  • 通过为密码和多因素认证添加额外检查来提升安全性
  • 通过集成外部认证系统的身份凭证来支持遗留系统
  • 向 JWT 添加额外的自定义声明
  • 通过自定义提供商发送认证邮件或短信

当前可用的钩子包括:

钩子适用计划
自定义访问令牌免费版、专业版
发送短信免费版、专业版
发送邮件免费版、专业版
MFA验证尝试团队版和企业版
密码验证尝试团队版和企业版

Supabase 支持两种方式在项目中配置钩子

可以将 Postgres 函数配置为钩子。该函数应接收单个参数——JSONB 类型的事件——并返回一个 JSONB 对象。由于 Postgres 函数在您的数据库上运行,请求不会离开项目实例。

安全模型

通过签名负载和选择性授权来保障负载的完整性。

当您将Postgres函数配置为钩子时,Supabase会自动为函数应用以下授权,原因如下:

  • 允许supabase_auth_admin角色执行该函数。supabase_auth_admin角色是Supabase Auth用于向数据库发起请求的Postgres角色。
  • 撤销其他角色(如anonauthenticatedpublic)的权限,确保Supabase数据API无法访问该函数。
1
2
3
4
5
6
7
8
9
10
11
12
-- 授予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>

1
2
3
[auth.hook.<hook_name>]enabled = trueuri = "pg-functions://...."

需要分配额外权限,使Supabase Auth可以访问Hook及其交互的表。

supabase_auth_admin角色没有public模式的权限。需要授予该角色执行Hook的权限:

1
2
3
grant execute on function public.custom_access_token_hook to supabase_auth_admin;

还需要授予supabase_auth_admin使用权限:

1
grant usage on schema public to supabase_auth_admin;

同时撤销authenticatedanon角色的权限,确保函数无法通过Supabase无服务器API访问。

1
2
3
revoke 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创建迁移。

以下是Hook签名示例:

1
2
3
4
5
6
7
8
9
10
11
create 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响应中返回的消息(必需)

示例:

1
2
3
4
5
6
{ "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测试工具来模拟请求。