认证

多因素认证验证钩子


您可以通过钩子为 Supabase MFA 实现 添加额外的检查。例如,您可以:

  • 限制在一定时间段内的验证尝试次数
  • 对验证尝试失败过多的用户执行登出操作
  • 统计、限流或封禁登录行为

输入参数

Supabase Auth 会向您的钩子发送包含以下字段的有效载荷:

字段类型描述
factor_idstring待验证MFA因子的唯一标识符
factor_typestringtotpphone
user_idstring用户的唯一标识符
validboolean验证尝试是否有效。对于TOTP,表示六位数验证码是否正确(true为正确,false为错误)。
1
2
3
4
5
{ "factor_id": "6eab6a69-7766-48bf-95d8-bd8f606894db", "user_id": "3919cb6e-4215-4478-a960-6d3454326cec", "valid": true}

输出

当您的钩子成功处理输入且无错误时返回以下内容。

字段类型描述
decisionstring是否允许继续认证的决策。使用 reject 拒绝验证尝试并注销用户所有活动会话。使用 continue 则采用 Supabase Auth 的默认行为。
messagestring当决策为 reject 时显示给用户的消息。
1
2
3
4
{ "decision": "reject", "message": "您已超过MFA验证的最大尝试次数。"}

您的公司要求用户输入错误的MFA验证码后,必须间隔至少2秒才能再次尝试。

创建表记录用户针对某个验证因素的最后一次失败尝试时间。

1
2
3
4
5
6
create table public.mfa_failed_verification_attempts ( user_id uuid not null, factor_id uuid not null, last_failed_at timestamp not null default now(), primary key (user_id, factor_id));

创建钩子函数来读写该表数据。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
create function public.hook_mfa_verification_attempt(event jsonb) returns jsonb language plpgsqlas $$ declare last_failed_at timestamp; begin if event->'valid' is true then -- 验证码有效,接受 return jsonb_build_object('decision', 'continue'); end if; select last_failed_at into last_failed_at from public.mfa_failed_verification_attempts where user_id = event->'user_id' and factor_id = event->'factor_id'; if last_failed_at is not null and now() - last_failed_at < interval '2 seconds' then -- 上次尝试间隔太短 return jsonb_build_object( 'error', jsonb_build_object( 'http_code', 429, 'message', '请稍后再试。' ) ); end if; -- 记录本次失败尝试 insert into public.mfa_failed_verification_attempts ( user_id, factor_id, last_refreshed_at ) values ( event->'user_id', event->'factor_id', now() ) on conflict do update set last_refreshed_at = now(); -- 最终让Supabase Auth处理失败的默认行为 return jsonb_build_object('decision', 'continue'); end;$$;-- 分配适当权限并撤销访问grant all on table public.mfa_failed_verification_attempts to supabase_auth_admin;revoke all on table public.mfa_failed_verification_attempts from authenticated, anon, public;