Skip to content
Auth

身份验证钩子

Use HTTP or Postgres Functions to customize your authentication flow

钩子是什么 #

🌐 What is a hook

钩子是一个端点,它允许你在特定的执行点更改默认的 Supabase 身份验证流程。开发者可以使用钩子来添加原生不支持的自定义行为。

🌐 A hook is an endpoint that allows you to alter the default Supabase Auth flow at specific execution points. Developers can use hooks to add custom behavior that's not supported natively.

Hooks 可以帮你:

🌐 Hooks help you:

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

以下钩子可用:

🌐 The following hooks are available:

钩子可用计划
用户创建前免费, 专业版
自定义访问令牌免费, 专业版
发送短信免费, 专业版
发送邮件免费, 专业版
多因素验证尝试团队版和企业版
密码验证尝试团队版和企业版

Supabase 支持在你的项目中通过两种方式配置钩子

🌐 Supabase supports 2 ways to configure a hook in your project:

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

🌐 A Postgres function can be configured as a hook. The function should take in a single argument -- the event of type JSONB -- and return a JSONB object. Since the Postgres function runs on your database, the request does not leave your project's instance.

安全模型 #

🌐 Security model

对有效载荷进行签名,并有选择地授予权限,以保护有效载荷的完整性。

🌐 Sign the payload and grant permissions selectively in order to guard the integrity of the payload.

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

🌐 When you configure a Postgres function as a hook, Supabase will automatically apply the following grants to the function for these reasons:

  • 允许 supabase_auth_admin 角色执行该功能。supabase_auth_admin 角色是 Supabase Auth 用来向你的数据库发出请求的 Postgres 角色。
  • 撤销其他角色(例如 anonauthenticatedpublic)的权限,以确保 Supabase 数据 API 无法访问该功能。
1
-- Grant access to function to supabase_auth_admin
2
grant execute
3
on function public.custom_access_token_hook
4
to supabase_auth_admin;
5
6
-- Grant access to schema to supabase_auth_admin
7
grant usage on schema public to supabase_auth_admin;
8
9
-- Revoke function permissions from authenticated, anon and public
10
revoke execute
11
on function public.custom_access_token_hook
12
from authenticated, anon, public;

你需要修改你的行级安全(RLS)策略,以允许 supabase_auth_admin 角色访问你已经设置了 RLS 策略的表。你可以在 这里 阅读更多关于 RLS 策略的信息。

🌐 You will need to alter your row-level security (RLS) policies to allow the supabase_auth_admin role to access tables that you have RLS policies on. You can read more about RLS policies here.

或者,你可以通过仪表板使用 security definer 标签创建你的 Postgres 函数。security definer 标签则表示函数将以拥有它的用户的权限执行。

🌐 Alternatively, you can create your Postgres function via the dashboard with the security definer tag. The security definer tag specifies that the function is to be executed with the privileges of the user that owns it.

目前,通过仪表板创建的函数会获取 postgres 角色。想了解关于 security definer 标签的更多信息,请查看我们的数据库指南 在这里

🌐 Currently, functions created via the dashboard take on the postgres role. Read more about the security definer tag in our database guide

使用 Hooks #

🌐 Using Hooks

开发中 #

🌐 Developing

让我们先在本地开发一个 Hook,然后再部署到云端。回顾一下,这里有一个可用 Hook 的列表

🌐 Let us develop a Hook locally and then deploy it to the cloud. As a recap, here’s a list of available Hooks

钩子建议的函数名称调用时机功能说明
发送短信send_sms每次发送短信时允许你自定义消息内容和短信提供商
发送邮件send_email每次发送邮件时允许你自定义消息内容和邮件提供商
自定义访问令牌custom_access_token每次创建新的 JWT 时返回你希望在 JWT 中包含的声明
多因素验证尝试mfa_verification_attempt每次用户尝试验证 MFA 因子时返回是否拒绝此次及未来尝试,或允许用户继续尝试的决定
密码验证尝试password_verification_attempt每次用户尝试使用密码登录时返回是否允许用户拒绝尝试,或允许用户继续尝试的决定

编辑 config.toml 来本地设置认证钩子。

🌐 Edit config.toml to set up the Auth Hook locally.

Modify the auth.hook.<hook_name> field and set uri to a value of pg-functions://postgres/<schema>/<function_name>

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

你需要分配额外的权限,这样 Supabase Auth 才能访问这个钩子以及它要操作的表。

🌐 You need to assign additional permissions so that Supabase Auth can access the hook as well as the tables it interacts with.

supabase_auth_admin 角色没有 public 模式的权限。你需要给这个角色授权以执行你的钩子:

🌐 The supabase_auth_admin role does not have permissions to the public schema. You need to grant the role permission to execute your hook:

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

你还需要给 supabase_auth_admin 授权使用:

🌐 You also need to grant usage to supabase_auth_admin:

1
grant usage on schema public to supabase_auth_admin;

还要撤销 authenticatedanon 角色的权限,以确保 Supabase Serverless API 无法访问这个功能。

🌐 Also revoke permissions from the authenticated and anon roles to ensure the function is not accessible by Supabase Serverless APIs.

1
revoke execute
2
on function public.custom_access_token_hook
3
from authenticated, anon;

出于安全考虑,我们建议不要使用 security definer 标签。security definer 标签表示函数将以拥有它的用户的权限执行。当通过 Supabase 仪表板使用该标签创建函数时,它将拥有 postgres 角色的广泛权限,这可能更容易发生不希望的操作。

🌐 For security, we recommend against the use the security definer tag. The security definer tag specifies that the function is to be executed with the privileges of the user that owns it. When a function is created via the Supabase dashboard with the tag, it will have the extensive permissions of the postgres role which make it easier for undesirable actions to occur.

我们建议你不要使用任何标签,并按照上面描述的那样明确授予 supabase_auth_admin 权限。

🌐 We recommend that you do not use any tag and explicitly grant permissions to supabase_auth_admin as described above.

在我们的数据库指南中了解更多关于 security definer 标签的信息 点击这里

🌐 Read more about security definer tag in our database guide.

完成后,将你的身份验证 Hook 保存为迁移,以便对身份验证 Hook 进行版本控制并与其他团队成员共享。运行 supabase migration new 来创建迁移。

🌐 Once done, save your Auth Hook as a migration in order to version the Auth Hook and share it with other team members. Run supabase migration new to create a migration.

这里是一个示例钩子签名:

🌐 Here is an example hook signature:

1
create or replace function public.custom_access_token_hook(event jsonb)
2
returns jsonb
3
language plpgsql
4
as $$
5
declare
6
-- Insert variables here
7
begin
8
-- Insert logic here
9
return event;
10
end;
11
$$;

你可以去 SQL Editor > Templates 查看 hook 模板。

🌐 You can visit SQL Editor > Templates for hook templates.

部署中 #

🌐 Deploying

在仪表板中,导航到 Authentication > Hooks,然后从下拉菜单中选择合适的功能类型(SQL 或 HTTP)。

🌐 In the dashboard, navigate to Authentication > Hooks and select the appropriate function type (SQL or HTTP) from the dropdown menu.

错误处理 #

🌐 Error handling

当遇到运行时错误时,你应该返回一个错误。运行时错误是针对你的应用的,通常是由特定的业务规则引起的,而不是程序员的错误。

🌐 You should return an error when facing a runtime error. Runtime errors are specific to your application and arise from specific business rules rather than programmer errors.

运行时错误可能会发生在:

🌐 Runtime errors could happen when:

  • 用户没有相应的权限
  • 收到的事件负载没有必要的声明。
  • 用户执行了一个违反业务规则的操作。
  • 在 webhook 中使用的电子邮件或电话提供商返回了一个错误。

这个错误是一个 JSON 对象,并且具有以下属性:

🌐 The error is a JSON object and has the following properties:

  • error 一个包含错误信息的对象。
    • http_code 表示要返回的 HTTP 状态码。如果未设置,则默认返回 HTTP 500 内部服务器错误。
    • message 要在HTTP响应中返回的消息。必填。

这里有一个例子:

🌐 Here's an example:

1
{
2
"error": {
3
"http_code": 429,
4
"message": "You can only verify a factor once every 10 seconds."
5
}
6
}

从 Postgres 钩子返回的错误是无法重试的。当返回错误时,错误会从钩子传递到 Supabase Auth,并被转换成 HTTP 错误返回给你的应用。Supabase Auth 只会考虑这个错误,其他的负载则会被忽略。

🌐 Errors returned from a Postgres Hook are not retry-able. When an error is returned, the error is propagated from the hook to Supabase Auth and translated into an HTTP error which is returned to your application. Supabase Auth will only take into account the error and disregard the rest of the payload.

除了运行时错误外,HTTP Hooks 和 Postgres Hooks 都会返回超时错误。Postgres Hooks 有 2 秒来完成处理,而 HTTP Hooks 应该在 5 秒内完成。HTTP Hooks 和 Postgres Hooks 都在事务中运行,以限制执行时间,避免延迟认证流程。

可用钩子 #

🌐 Available Hooks

每个 Hook 描述都包含一个示例 JSON Schema,你可以将其与 JSON Schema Faker 一起使用,以生成模拟的 payload。对于 HTTP Hooks,你也可以使用 标准 Webhooks 测试工具 来模拟请求。

🌐 Each Hook description contains an example JSON Schema which you can use in conjunction with JSON Schema Faker in order to generate a mock payload. For HTTP Hooks, you can also use the Standard Webhooks Testing Tool to simulate a request.