Supabase Google 登录 - 常规设置
本指南将引导您使用 Capacitor 社交登录插件将 Google 登录与 Supabase 身份验证集成。此设置允许您在移动平台上使用本机 Google 登录,同时利用 Supabase Auth 进行后端身份验证。
开始之前,请确保您拥有:
-
阅读 Google 登录常规设置 指南以设置 Google OAuth 凭据
-
按照相应平台特定的指南为您的目标平台设置 Google OAuth 凭据:
:::注意 在开始 Supabase 教程之前,您需要为您计划使用的平台生成客户端 ID。 您将在本指南的第 7 步中使用它们。 :::
在 Supabase 中启用 Google OAuth 提供程序
Section titled “在 Supabase 中启用 Google OAuth 提供程序”-
转到您的 Supabase 仪表板
-
单击您的项目

-
请转到
Authentication菜单
-
单击
Providers选项卡
-
找到
Google提供商
-
启用提供程序

-
添加您计划使用的平台的客户端 ID

:::注意 这包括 Web 客户端 ID、iOS 客户端 ID 和 Android 客户端 ID。您可以跳过提供其中一些,具体取决于您计划使用的平台。 :::
-
单击
Save按钮
瞧,您现在已启用 Google 使用 Supabase 身份验证登录 🎉
Google 使用 Supabase 身份验证助手登录的工作原理
Section titled “Google 使用 Supabase 身份验证助手登录的工作原理”本节介绍 Google 登录与 Supabase 的集成如何在后台工作。了解此流程将帮助您实施身份验证过程并排除故障。
:::提示[完整实施]
完整的实现可在 示例应用程序的 supabaseAuthUtils.ts 文件中找到。
:::
1.随机数生成
Section titled “1.随机数生成”该实现生成符合 Supabase 随机数要求 的安全随机数对:
// Generate URL-safe random noncefunction getUrlSafeNonce(): string { const array = new Uint8Array(32); crypto.getRandomValues(array); return Array.from(array, (byte) => byte.toString(16).padStart(2, '0')).join('');}
// Hash the nonce with SHA-256async function sha256Hash(message: string): Promise<string> { const encoder = new TextEncoder(); const data = encoder.encode(message); const hashBuffer = await crypto.subtle.digest('SHA-256', data); const hashArray = Array.from(new Uint8Array(hashBuffer)); return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');}
// Generate nonce pairasync function getNonce(): Promise<{ rawNonce: string; nonceDigest: string }> { const rawNonce = getUrlSafeNonce(); const nonceDigest = await sha256Hash(rawNonce); return { rawNonce, nonceDigest };}流量:
rawNonce:URL 安全随机字符串(64 个十六进制字符)nonceDigest:rawNonce的 SHA-256 哈希值(十六进制编码)nonceDigest传递到 Google 登录 → Google 在 ID 令牌中包含随机数摘要rawNonce传递给 Supabase → Supabase 哈希原始随机数并与令牌的随机数进行比较
2. Google 登录
Section titled “2. Google 登录”该函数初始化插件并使用 Google 登录:
await SocialLogin.initialize({ google: { webClientId: 'YOUR_WEB_CLIENT_ID.apps.googleusercontent.com', // iOS only: iOSClientId: 'YOUR_IOS_CLIENT_ID.apps.googleusercontent.com', mode: 'online', // Required to get idToken },});
const response = await SocialLogin.login({ provider: 'google', options: { scopes: ['email', 'profile'], nonce: nonceDigest, // Pass the SHA-256 hashed nonce },});3. JWT 验证
Section titled “3. JWT 验证”在将令牌发送到 Supabase 之前,实现会验证 JWT 令牌:
function validateJWTToken(idToken: string, expectedNonceDigest: string): { valid: boolean; error?: string } { const decodedToken = decodeJWT(idToken);
// Check audience matches your Google Client IDs const audience = decodedToken.aud; if (!VALID_GOOGLE_CLIENT_IDS.includes(audience)) { return { valid: false, error: 'Invalid audience' }; }
// Check nonce matches const tokenNonce = decodedToken.nonce; if (tokenNonce && tokenNonce !== expectedNonceDigest) { return { valid: false, error: 'Nonce mismatch' }; }
return { valid: true };}为什么要在 Supabase 之前验证?
在将令牌发送到 Supabase 之前验证 JWT 令牌有几个重要目的:
-
防止无效请求:如果令牌的受众不正确或随机数不匹配,Supabase 无论如何都会拒绝令牌。首先验证可以避免不必要的 API 调用并提供更清晰的错误消息。
-
令牌缓存问题:在某些平台(尤其是 iOS)上,Google 登录 SDK 可以缓存令牌以提高性能。返回缓存令牌时,缓存令牌可能是使用不同的随机数(或根本没有随机数)生成的,导致 Supabase 拒绝该令牌并出现“随机数不匹配”错误。通过在发送到 Supabase 之前进行验证,我们可以及早检测到此问题并使用新令牌自动重试。
-
安全性 (iOS):在 iOS 上,验证可确保为您的特定 Google 客户端 ID 颁发令牌,从而防止因使用用于其他应用程序的令牌而出现潜在的安全问题。
-
更好的错误处理:在 Supabase 之前检测问题允许自动重试逻辑,这对于透明地处理 iOS 缓存问题至关重要。
如果验证失败,该函数会自动:
- 从 Google 注销(清除缓存的令牌 - 对 iOS 至关重要)
- 重试身份验证一次(强制使用正确的随机数生成新的令牌) 3.如果重试也失败,则返回错误
4. Supabase 登录
Section titled “4. Supabase 登录”最后,验证后的令牌被发送到 Supabase:
const { data, error } = await supabase.auth.signInWithIdToken({ provider: 'google', token: googleResponse.idToken, nonce: rawNonce, // Pass the raw (unhashed) nonce});完整代码参考
Section titled “完整代码参考”完整的实现可在 示例应用程序的 supabaseAuthUtils.ts 文件中找到,其中包括:
getUrlSafeNonce()- 生成 URL 安全随机数sha256Hash()- 使用 SHA-256 哈希字符串getNonce()- 生成随机数对decodeJWT()- 解码 JWT 令牌validateJWTToken()- 验证 JWT 受众和随机数authenticateWithGoogleSupabase()- 带自动重试的主要身份验证功能
其他示例文件
Section titled “其他示例文件”- SupabasePage.tsx - 具有重定向处理功能的示例组件 (Web)
- SupabaseCreateAccountPage.tsx - 创建帐户页面示例
请继续阅读您的目标平台的特定于平台的设置指南: