使用 Web3 登录
Use your Web3 wallet to authenticate users with Supabase
启用 Web3 登录,让用户只用他们的 Web3 钱包就能登录你的应用。
支持的 Web3 钱包:
🌐 Supported Web3 wallets:
- 所有 Solana 钱包
- 所有以太坊钱包
它是怎么运作的? #
🌐 How does it work?
使用 Web3 登录采用 EIP 4361 标准来进行链下钱包地址验证。这个标准在以太坊和 Solana 生态系统中被广泛支持,因此是验证钱包所有权的最佳选择。
🌐 Sign in with Web3 uses the EIP 4361 standard to authenticate wallet addresses off-chain. This standard is widely supported by the Ethereum and Solana ecosystems, making it the best choice for verifying wallet ownership.
认证的工作方式是让 Web3 钱包应用使用用户的钱包签署一条预定义的消息。这条消息会被 Web3 钱包应用和 Supabase Auth 一起解析,以验证其有效性和目的,然后再创建用户账户或会话。
🌐 Authentication works by asking the Web3 wallet application to sign a predefined message with the user's wallet. This message is parsed both by the Web3 wallet application and Supabase Auth to verify its validity and purpose, before creating a user account or session.
这样一条消息的例子是:
🌐 An example of such a message is:
1example.com wants you to sign in with your Ethereum account:20xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc234I accept the ExampleOrg Terms of Service: https://example.com/tos56URI: https://example.com/login7Version: 18Chain ID: 19Nonce: 3289175610Issued At: 2021-09-30T16:25:24Z11Resources:12- https://example.com/my-web2-claim.json它定义了钱包地址、时间戳、登录发生的浏览器位置,并包含一个可自定义的声明(I accept...),你可以用它来征求用户的同意。
🌐 It defines the wallet address, timestamp, browser location where the sign-in occurred and includes a customizable statement (I accept...) which you can use to ask consent from the user.
大多数 Web3 钱包都能识别这些信息,并显示一个专门的“确认登录”对话框,以安全且负责任的方式验证并呈现信息给用户。即使钱包不直接支持这些信息,也会改为使用消息签名对话框。
🌐 Most Web3 wallets are able to recognize these messages and show a dedicated "Confirm Sign In" dialog validating and presenting the information in the message in a secure and responsible way to the user. Even if the wallet does not directly support these messages, it will use the message signature dialog instead.
最后,Supabase Auth 服务器会在向你的应用发放有效的 用户会话 前,验证消息的内容和签名。验证规则包括:
🌐 Finally the Supabase Auth server validates both the message's contents and signature before issuing a valid User session to your application. Validation rules include:
- 消息结构验证
- 加密签名验证
- 时间戳验证,确保签名是在登录调用后的10分钟内创建的
- URI 和域名验证,确保它们与你服务器定义的 重定向 URL 匹配
钱包地址用作身份标识,在身份数据中你还可以找到声明和额外的元数据。
🌐 The wallet address is used as the identity identifier, and in the identity data you can also find the statement and additional metadata.
启用 Web3 提供者 #
🌐 Enable the Web3 provider
在仪表板中,导航到你项目的身份验证提供商部分,并启用 Web3 钱包提供商。
🌐 In the dashboard navigate to your project's Authentication Providers section and enable the Web3 Wallet provider.
在命令行接口中,将以下配置添加到你的 supabase/config.toml 文件:
🌐 In the CLI add the following config to your supabase/config.toml file:
1[auth.web3.solana]2enabled = true34[auth.web3.ethereum]5enabled = true滥用的可能性 #
🌐 Potential for abuse
使用 Web3 钱包登录的用户账户将不会关联电子邮件地址或电话号码。这可能会让你的项目容易被滥用,因为创建 Web3 钱包账户是免费的、容易自动化的,并且很难与真实身份关联。
🌐 User accounts that sign in with their Web3 wallet will not have an email address or phone number associated with them. This can open your project to abuse as creating a Web3 wallet account is free and easy to automate and difficult to correlate with a real person's identity.
在仪表板中配置来控制你项目的曝光度:
🌐 Control your project's exposure by configuring in the dashboard:
或者在命令行接口中:
🌐 Or in the CLI:
1[auth.rate_limit]2# Number of Web3 logins that can be made in a 5 minute interval per IP address.3web3 = 3045[auth.captcha]6enabled = true7provider = "hcaptcha" # or other supported providers8secret = "0x0000000000000000000000000000000000000000"许多钱包应用会在发送签名消息时提醒用户,如果消息不是来自他们当前访问的页面。为了进一步防止你的 Supabase 项目收到原本该发给其他应用的已签名消息,你必须使用 重定向 URL 设置 注册你的应用 URL。
🌐 Many wallet applications will warn the user if the message sent for signing is not coming from the page they are currently visiting. To further prevent your Supabase project from receiving signed messages destined for other applications, you must register your application's URL using the Redirect URL settings.
例如,如果用户正在登录页面 https://example.com/sign-in,你应该在重定向 URL 设置中添加以下配置:
🌐 For example if the user is signing in to the page https://example.com/sign-in you should add the following configurations in the Redirect URL settings:
https://example.com/sign-in/(最后的斜杠很重要)- 或者设置一个全局模式,比如
https://example.com/**
用以太坊登录 #
🌐 Sign in with Ethereum
以太坊定义了window.ethereum 全局作用域对象,你的应用可以用它来与以太坊钱包进行交互。此外,还有一个钱包发现机制(EIP-6963),你的应用可以用它来发现用户浏览器上所有可用的钱包。
🌐 Ethereum defines the window.ethereum global scope object that your app uses to interact with Ethereum Wallets. Additionally there is a wallet discovery mechanism (EIP-6963) that your app can use to discover all of the available wallets on the user's browser.
要使用以太坊钱包登录用户,请确保用户已经安装了钱包应用。有两种方法可以做到这一点:
🌐 To sign in a user with their Ethereum wallet make sure that the user has installed a wallet application. There are two ways to do this:
- 检测
window.ethereum全局作用域对象,并确保它已定义。只有当用户的浏览器上只安装了一个钱包时,这才有效。 - 使用钱包发现机制(EIP-6963)让用户在继续登录前选择一个钱包。阅读 MetaMask 关于支持此操作的最佳方法指南。
使用以下代码登录用户,默认依赖 window.ethereum 全局作用域钱包 API:
🌐 Use the following code to sign in a user, implicitly relying on the window.ethereum global scope wallet API:
1const { data, error } = await supabase.auth.signInWithWeb3({2 chain: 'ethereum',3 statement: 'I accept the Terms of Service at https://example.com/tos',4})使用 Solana 登录 #
🌐 Sign in with Solana
大多数 Solana 钱包应用会通过你网页应用里的 window.solana 全局对象来提供它们的 API。
🌐 Most Solana wallet applications expose their API via the window.solana global scope object in your web application.
Supabase 的 JavaScript 客户端库内置支持这个 API。
🌐 Supabase's JavaScript Client Library provides built-in support for this API.
要登录用户,请确保:
🌐 To sign in a user make sure that:
- 用户已经安装了一个钱包应用(通过检查
window.solana对象是否已定义) - 钱包应用通过使用
window.solana.connect()API连接到你的应用
使用以下代码来验证用户:
🌐 Use the following code to authenticate a user:
1const { data, error } = await supabase.auth.signInWithWeb3({2 chain: 'solana',3 statement: 'I accept the Terms of Service at https://example.com/tos',4})提供 statement 是大多数 Solana 钱包所必需的,这条信息会在用户的同意对话框中显示给他们。它也会被添加到你用户的身份数据中。
🌐 Providing a statement is required for most Solana wallets and this message will be shown to the user on the consent dialog. It will also be added to the identity data for your users.
如果你使用的是不注册 window.solana 对象的非标准 Solana 钱包,或者你的用户在页面上连接了多个 Solana 钱包,你可以通过这样提供钱包对象来消除歧义:
🌐 If you are using a non-standard Solana wallet that does not register the window.solana object, or your user has multiple Solana wallets attached to the page you can disambiguate by providing the wallet object like so:
-
要使用 Brave 钱包与 Solana:
1const { data, error } = await supabase.auth.signInWithWeb3({2chain: 'solana',3statement: 'I accept the Terms of Service at https://example.com/tos',4wallet: window.braveSolana,5}) -
要使用 Phantom 和 Solana :
1const { data, error } = await supabase.auth.signInWithWeb3({2chain: 'solana',3statement: 'I accept the Terms of Service at https://example.com/tos',4wallet: window.phantom,5})
常见问题 #
🌐 Frequently asked questions
如何将邮箱地址、电话号码或社交登录与使用 Web3 登录的用户关联起来? #
🌐 How to associate an email address, phone number or social login to a user signing in with Web3?
Web3 钱包除了钱包地址(公钥)之外,不会泄露用户的任何身份信息。这就是为什么使用 Web3 登录创建的账户没有关联任何邮箱或电话号码的原因。
🌐 Web3 wallets don't expose any identifying information about the user other than their wallet address (public key). This is why accounts that were created using Sign in with Web3 don't have any email address or phone number associated.
要将电子邮件地址、电话号码或其他社交登录与他们的账户关联,你可以使用 supabase.auth.updateUser() 或 supabase.auth.linkIdentity() API。
🌐 To associate an email address, phone number or other social login with their account you can use the supabase.auth.updateUser() or supabase.auth.linkIdentity() APIs.