PKCE 流程
About authenticating with PKCE flow.
代码交换的验证密钥(PKCE)流程是用户可以认证的一种方式,同时你的应用也能获取必要的访问和刷新令牌。
🌐 The Proof Key for Code Exchange (PKCE) flow is one of two ways that a user can authenticate and your app can receive the necessary access and refresh tokens.
这个流程是由 Supabase Auth 为你处理的实现细节,但理解 PKCE 和 隐式流程 之间的区别,对于理解仅客户端认证和服务器端认证的区别很重要。
🌐 The flow is an implementation detail handled for you by Supabase Auth, but understanding the difference between PKCE and implicit flow is important for understanding the difference between client-only and server-side auth.
它是怎么运作的 #
🌐 How it works
验证成功后,用户会被重定向到你的应用,网址看起来像这样:
🌐 After a successful verification, the user is redirected to your app with a URL that looks like this:
1https://yourapp.com/...?code=<...>code 参数通常被称为认证码,可以通过调用 exchangeCodeForSession(code) 来交换访问令牌。
🌐 The code parameter is commonly known as the Auth Code and can be exchanged for an access token by calling exchangeCodeForSession(code).
为了安全起见,这个代码有效期为5分钟,并且只能兑换一次访问令牌。如果你想获得新的访问令牌,需要从头重新开始认证流程。
🌐 For security purposes, the code has a validity of 5 minutes and can only be exchanged for an access token once. You will need to restart the authentication flow from scratch if you wish to obtain a new access token.
由于流程是在服务器端运行的,localStorage 可能不可用。你可以通过将 storage 选项设置为包含以下方法的对象,来配置客户端库使用自定义存储适配器和备用存储(例如 cookies):
🌐 As the flow is run server side, localStorage may not be available. You may configure the client library to use a custom storage adapter and an alternate backing storage such as cookies by setting the storage option to an object with the following methods:
1import { type SupportedStorage } from '@supabase/supabase-js';2const supportsLocalStorage = () => true34// ---cut---5const customStorageAdapter: SupportedStorage = {6 getItem: (key) => {7 if (!supportsLocalStorage()) {8 // Configure alternate storage9 return null10 }11 return globalThis.localStorage.getItem(key)12 },13 setItem: (key, value) => {14 if (!supportsLocalStorage()) {15 // Configure alternate storage here16 return17 }18 globalThis.localStorage.setItem(key, value)19 },20 removeItem: (key) => {21 if (!supportsLocalStorage()) {22 // Configure alternate storage here23 return24 }25 globalThis.localStorage.removeItem(key)26 },27}你也可以配置客户端库在成功重定向后自动将其交换为会话。这可以通过将 detectSessionInUrl 选项设置为 true 来完成。
🌐 You may also configure the client library to automatically exchange it for a session after a successful redirect. This can be done by setting the detectSessionInUrl option to true.
综合起来,你的客户端库初始化可能看起来像这样:
🌐 Putting it all together, your client library initialization may look like this:
1import { createClient } from '@supabase/supabase-js'23// ---cut---4const supabase = createClient('https://your-project-id.supabase.co', 'sb_publishable_...', {5 // ...6 auth: {7 // ...8 detectSessionInUrl: true,9 flowType: 'pkce',10 storage: {11 getItem: () => Promise.resolve('FETCHED_TOKEN'),12 setItem: () => {},13 removeItem: () => {},14 },15 },16 // ...17})限制 #
🌐 Limitations
在幕后,代码交换需要一个代码验证器。URL里的代码和代码验证器都会被发送回认证服务器以完成交换。
🌐 Behind the scenes, the code exchange requires a code verifier. Both the code in the URL and the code verifier are sent back to the Auth server for a successful exchange.
当身份验证流程首次启动时,代码验证器会被创建并保存在本地。这意味着代码交换必须在启动流程的同一浏览器和设备上进行。
🌐 The code verifier is created and stored locally when the Auth flow is first initiated. That means the code exchange must be initiated on the same browser and device where the flow was started.
资源 #
🌐 Resources
- OAuth 2.0 指南 到 PKCE 流程