认证

匿名登录

创建并使用匿名用户进行 Supabase 认证


启用匿名登录 以构建应用程序,为用户提供经过身份验证的体验,而无需用户输入电子邮件地址、密码、使用 OAuth 提供商或提供任何其他个人身份信息(PII)。之后,当准备好时,用户可以将其账户关联到一个身份验证方法。

匿名登录可用于构建:

  • 电子商务应用程序,例如结账前的购物车
  • 无需收集个人信息的全功能演示
  • 临时或一次性账户

匿名登录

调用 signInAnonymously() 方法:

1
const { , } = await ..()

将匿名用户转换为永久用户

将匿名用户转换为永久用户需要将身份关联到该用户。这要求您在 Supabase 项目中启用手动关联

关联电子邮件/电话身份

您可以使用 updateUser() 方法将电子邮件或电话身份关联到匿名用户。要为匿名用户添加密码,需要先验证用户的电子邮件或电话号码。

1
2
3
4
5
6
7
8
9
10
const { : , : } = await ..({ : 'valid.email@supabase.io',})// 通过点击电子邮件更改链接或输入发送到电子邮件地址的6位OTP来验证用户电子邮件// 用户验证成功后,更新密码const { : , : } = await ..({ : 'password',})

关联OAuth身份

您可以使用 linkIdentity() 方法将OAuth身份关联到匿名用户。

1
const { , } = await ..({ : 'google' })

访问控制

匿名用户与永久用户一样,都承担 authenticated 角色。您可以使用行级安全(RLS)策略,通过检查 auth.jwt() 返回的 JWT 中 is_anonymous 声明来区分匿名用户和永久用户:

1
2
3
4
5
6
7
8
9
create policy "Only permanent users can post to the news feed"on news_feed as restrictive for insertto authenticatedwith check ((select (auth.jwt()->>'is_anonymous')::boolean) is false );create policy "Anonymous and permanent users can view the news feed"on news_feed for selectto authenticatedusing ( true );

解决身份冲突

根据您的应用程序需求,当匿名用户转换为永久用户时,可能会出现数据冲突。例如,在电子商务应用程序中,匿名用户无需注册/登录即可将商品添加到购物车。当他们决定登录现有账户时,您需要决定如何解决购物车中的数据冲突:

  1. 用现有账户中的商品覆盖购物车中的商品
  2. 用匿名用户购物车中的商品覆盖现有账户中的商品
  3. 合并购物车中的商品

将匿名用户关联到现有账户

在某些情况下,您可能需要将匿名用户关联到现有账户,而不是创建一个新的永久账户。此过程需要手动处理潜在的冲突。以下是一个通用方法:

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
// 1. 匿名登录(假设用户已匿名登录)const { data: anonData, error: anonError } = await supabase.auth.getSession()// 2. 尝试使用现有邮箱更新用户const { data: updateData, error: updateError } = await supabase.auth.updateUser({ email: 'valid.email@supabase.io',})// 3. 处理错误(因为该邮箱属于现有用户)if (updateError) { console.log('此邮箱属于现有用户。请登录该账户。') // 4. 登录现有账户 const { data: { user: existingUser }, error: signInError, } = await supabase.auth.signInWithPassword({ email: 'valid.email@supabase.io', password: 'user_password', }) if (existingUser) { // 5. 重新分配与匿名用户关联的实体 // 此步骤将根据您的具体用例和数据模型而异 const { data: reassignData, error: reassignError } = await supabase .from('your_table') .update({ user_id: existingUser.id }) .eq('user_id', anonData.session.user.id) // 6. 实现您选择的冲突解决策略 // 这可能涉及数据合并、覆盖或其他自定义逻辑 await resolveDataConflicts(anonData.session.user.id, existingUser.id) }}// 辅助函数,用于解决数据冲突(根据您的策略实现)async function resolveDataConflicts(anonymousUserId, existingUserId) { // 在此处实现您的冲突解决逻辑 // 这可能涉及忽略匿名用户的元数据、覆盖现有用户的元数据,或合并匿名用户和现有用户的数据。}

滥用防护与速率限制

由于匿名用户存储在您的数据库中,恶意行为者可能会滥用该端点,导致您的数据库大小急剧增加。强烈建议启用隐形验证码或 Cloudflare Turnstile,以防止匿名登录被滥用。系统会强制执行每小时30次请求的基于IP的速率限制,您可以在控制台中修改此设置。您可以在此处查看完整的速率限制列表。

自动清理

目前不支持匿名用户的自动清理功能。相反,您可以通过运行以下SQL从项目中删除匿名用户:

1
2
3
-- 删除30天前创建的匿名用户delete from auth.userswhere is_anonymous is true and created_at < now() - interval '30 days';

资源