无密码邮箱登录
Email logins using Magic Links or One-Time Passwords (OTPs)
Supabase Auth 提供了几种无密码登录方式。无密码登录让用户无需密码即可登录,只需点击确认链接或输入验证码。
🌐 Supabase Auth provides several passwordless login methods. Passwordless logins allow users to sign in without a password, by clicking a confirmation link or entering a verification code.
无密码登录可以:
🌐 Passwordless login can:
- 通过不要求用户创建和记住密码来提升用户体验
- 通过降低与密码相关的安全漏洞风险来提高安全性
- 减少处理密码重置和其他与密码相关流程的支持负担
Supabase Auth 提供两种无需密码的登录方式,使用的是用户的电子邮箱:
🌐 Supabase Auth offers two passwordless login methods that use the user's email address:
使用魔法链接 #
🌐 With Magic Link
魔法链接是一种无密码登录方式,用户只需点击发送到他们邮箱的链接就能登录账号。魔法链接仅适用于邮箱,而且每个链接只能使用一次。
🌐 Magic Links are a form of passwordless login where users click on a link sent to their email address to log in to their accounts. Magic Links only work with email addresses and are one-time use only.
启用魔法链接 #
🌐 Enabling Magic Link
电子邮件认证方法,包括魔法链接,默认是启用的。
🌐 Email authentication methods, including Magic Links, are enabled by default.
配置网站网址和任何额外的重定向网址。这些是用户点击魔法链接后被允许作为重定向目标的网址。你可以在托管项目的网址配置页面上更改网址,在本地开发的config.toml文件中更改,或者在自托管 Supabase的.env配置文件中更改。
🌐 Configure the Site URL and any additional redirect URLs. These are the only URLs that are allowed as redirect destinations after the user clicks a Magic Link. You can change the URLs on the URL Configuration page for hosted projects, in the config.toml file for local development, or in the .env configuration file for self-hosted Supabase.
默认情况下,用户每 60 seconds 只能请求一次魔法链接,并且魔法链接会在 1 hour后过期。
使用魔法链接登录 #
🌐 Signing in with Magic Link
从客户端库调用“使用一次性密码登录”的方法。
🌐 Call the "sign in with OTP" method from the client library.
虽然这种方法被标记为“OTP”,但它默认发送的是魔法链接。这两种方法的区别仅在于发送给用户的确认邮件内容。
🌐 Though the method is labelled "OTP", it sends a Magic Link by default. The two methods differ only in the content of the confirmation email sent to the user.
如果用户还没注册,他们会默认被自动注册。要防止这种情况,把 shouldCreateUser 选项设置为 false。
🌐 If the user hasn't signed up yet, they are automatically signed up by default. To prevent this, set the shouldCreateUser option to false.
1import { createClient } from '@supabase/supabase-js'23const supabase = createClient('https://your-project-id.supabase.co', 'sb_publishable_...')45// ---cut---6async function signInWithEmail() {7 const { data, error } = await supabase.auth.signInWithOtp({8 email: 'valid.email@supabase.io',9 options: {10 // set this to false if you do not want the user to be automatically signed up11 shouldCreateUser: false,12 emailRedirectTo: 'https://example.com/welcome',13 },14 })15}隐式流程就到这里了。
🌐 That's it for the implicit flow.
如果你正在使用 PKCE 流程,编辑 Magic Link 邮件模板 来发送一个令牌哈希:
🌐 If you're using PKCE flow, edit the Magic Link email template to send a token hash:
1<h2>Sign in to your account</h2>23<p>Use this link to sign in to your account:</p>4<p><a href="{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}&type=email">Sign in</a></p>在 /auth/confirm 端点,用哈希换取会话:
🌐 At the /auth/confirm endpoint, exchange the hash for the session:
1import { createClient } from '@supabase/supabase-js'23const supabase = createClient('https://your-project-id.supabase.co', 'sb_publishable_...')45// ---cut---6const { error } = await supabase.auth.verifyOtp({7 token_hash: 'hash',8 type: 'email',9})带一次性密码 #
🌐 With OTP
电子邮件一次性密码(OTP)是一种无密码登录方式,用户输入发送到他们邮箱的六位数代码来登录账户。
🌐 Email one-time passwords (OTP) are a form of passwordless login where users key in a six digit code sent to their email address to log in to their accounts.
启用邮箱一次性密码 #
🌐 Enabling email OTP
电子邮件认证方法,包括电子邮件一次性密码(OTP),默认已启用。
🌐 Email authentication methods, including Email OTPs, are enabled by default.
电子邮件一次性密码(OTP)的实现与魔法链接相同。要发送 OTP 而不是魔法链接,请修改 魔法链接 电子邮件模板。有关更多信息,请参阅电子邮件模板指南。
🌐 Email OTPs share an implementation with Magic Links. To send an OTP instead of a Magic Link, alter the Magic Link email template. Refer to the Email Templates guide for more information.
修改模板以包含 {{ .Token }} 变量,例如:
🌐 Modify the template to include the {{ .Token }} variable, for example:
1<h2>One time login code</h2>23<p>Please enter this code: {{ .Token }}</p>默认情况下,用户每 60 seconds只能请求一次一次性密码(OTP),并且它们会在 1 hour后过期。你可以通过 Authentication > Sign In / Providers > Auth Providers > Email > Email OTP expiration 来配置。强烈不建议将过期时间设置超过 86,400 秒(一天),并且只能通过 Management API 设置。上线前一定要先阅读 安全建议。
电子邮件一次性密码(OTP)过期设置同样影响魔法链接和其他电子邮件链接的有效性,包括确认、密码恢复、邮箱更改以及邀请链接。
🌐 The Email OTP Expiration setting also governs the validity of Magic Links and other email links, including confirmation, password recovery, email change, and invitation links.
使用邮箱一次性密码登录 #
🌐 Signing in with email OTP
第一步:发给用户一个一次性密码(OTP) #
🌐 Step 1: Send the user an OTP code
获取用户的邮箱,然后用你的客户端库调用“用一次性密码登录”的方法。
🌐 Get the user's email and call the "sign in with OTP" method from your client library.
如果用户还没注册,他们会默认被自动注册。要防止这种情况,把 shouldCreateUser 选项设置为 false。
🌐 If the user hasn't signed up yet, they are automatically signed up by default. To prevent this, set the shouldCreateUser option to false.
1import { createClient } from '@supabase/supabase-js'23const supabase = createClient('https://your-project-id.supabase.co', 'sb_publishable_...')45// ---cut---6const { data, error } = await supabase.auth.signInWithOtp({7 email: 'valid.email@supabase.io',8 options: {9 // set this to false if you do not want the user to be automatically signed up10 shouldCreateUser: false,11 },12})如果请求成功,你会收到一个包含 error: null 和 data 对象的响应,其中 user 和 session 都是 null。告诉用户检查他们的邮箱收件箱。
🌐 If the request is successful, you receive a response with error: null and a data object where both user and session are null. Let the user know to check their email inbox.
1{2 "data": {3 "user": null,4 "session": null5 },6 "error": null7}步骤 2:验证 OTP 以创建会话 #
🌐 Step 2: Verify the OTP to create a session
提供一个输入框,让用户输入一次性验证码。
🌐 Provide an input field for the user to enter their one-time code.
使用你的客户端库调用“verify OTP”方法,传入用户的电子邮件地址、验证码以及 email 类型:
🌐 Call the "verify OTP" method from your client library with the user's email address, the code, and a type of email:
1import { createClient } from '@supabase/supabase-js'23const supabase = createClient('https://your-project-id.supabase.co', 'sb_publishable_...')45// ---cut---6const {7 data: { session },8 error,9} = await supabase.auth.verifyOtp({10 email: 'email@example.com',11 token: '123456',12 type: 'email',13})如果成功,用户现在已登录,你会收到一个看起来像这样的有效会话:
🌐 If successful, the user is now logged in, and you receive a valid session that looks like:
1{2 "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNjI3MjkxNTc3LCJzdWIiOiJmYTA2NTQ1Zi1kYmI1LTQxY2EtYjk1NC1kOGUyOTg4YzcxOTEiLCJlbWFpbCI6IiIsInBob25lIjoiNjU4NzUyMjAyOSIsImFwcF9tZXRhZGF0YSI6eyJwcm92aWRlciI6InBob25lIn0sInVzZXJfbWV0YWRhdGEiOnt9LCJyb2xlIjoiYXV0aGVudGljYXRlZCJ9.1BqRi0NbS_yr1f6hnr4q3s1ylMR3c1vkiJ4e_N55dhM",3 "token_type": "bearer",4 "expires_in": 3600,5 "refresh_token": "LSp8LglPPvf0DxGMSj-vaQ",6 "user": {...}7}