跳转至正文

Supabase Google Login - 常规设置

GitHub

本指南将带你了解如何使用 Capacitor Social Login 插件,将 Google Sign-In 与 Supabase Authentication 进行集成。通过此配置,你可以在移动端使用原生的 Google Sign-In,同时利用 Supabase Auth 进行后端身份验证。

开始之前,请确保您已:

  1. 创建了 Supabase 项目

  2. 阅读 Google Login 常规设置 指南以配置 Google OAuth 凭据

  3. 按照各平台特定的指南,为您的目标平台配置 Google OAuth 凭据:

  1. 前往你的 Supabase Dashboard

  2. 点击你的项目

    Supabase 项目选择器
  3. 前往 Authentication 菜单

    Supabase Authentication 菜单
  4. 点击 Providers 标签页

    Supabase 提供商标签页
  5. 找到 Google 提供商

    Supabase Google Provider
  6. 启用该 Provider

    启用 Supabase Google Provider
  7. 添加你计划使用的各平台 Client ID

    添加 Supabase Google Provider Client ID
  8. 点击 Save 按钮

    保存 Supabase Google Provider

大功告成!你已成功启用 Supabase Authentication 的 Google 登录功能 🎉

Supabase Authentication Google 登录辅助工具的工作原理

“Supabase Authentication Helper 如何实现 Google Sign-In”章节

本节将深入解析 Google Sign-In 与 Supabase 集成的底层原理。理解这一流程将有助于你实现并排查身份验证过程中的问题。

该实现会根据以下要求生成一组安全的 nonce 对: Supabase nonce 要求:

// Generate URL-safe random nonce
function 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-256
async 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 pair
async function getNonce(): Promise<{ rawNonce: string; nonceDigest: string }> {
const rawNonce = getUrlSafeNonce();
const nonceDigest = await sha256Hash(rawNonce);
return { rawNonce, nonceDigest };
}

流程:

  • rawNonce:URL 安全的随机字符串(64 位十六进制字符)
  • nonceDigest: rawNonce (十六进制编码)
  • nonceDigest 传递给 Google Sign-In → Google 将 nonce 摘要包含在 ID token 中
  • rawNonce 传递给 Supabase → Supabase 对原始 nonce 进行哈希处理,并与 token 中的 nonce 进行比对

该函数初始化插件并使用 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
},
});

在将 token 发送到 Supabase 之前,实现逻辑会先验证 JWT token:

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 之前进行验证?

在将 token 发送到 Supabase 之前验证 JWT token 有以下几个重要作用:

  1. 防止无效请求:如果 token 的 audience 不正确或 nonce 不匹配,Supabase 最终也会拒绝该 token。预先验证可以避免不必要的 API 调用,并提供更清晰的错误信息。

  2. Token 缓存问题:在某些平台(尤其是 iOS)上,Google Sign-In SDK 为了性能可能会缓存 token。当返回缓存的 token 时,该 token 可能使用了不同的 nonce(或根本没有 nonce),导致 Supabase 因 “nonce mismatch” 错误而拒绝请求。通过在发送给 Supabase 之前进行验证,我们可以及早发现此问题并自动使用新 token 进行重试。

  3. 安全性 (iOS):在 iOS 上,验证可以确保 token 是针对您特定的 Google Client IDs 签发的,从而防止因使用其他应用的 token 而导致的潜在安全问题。

  4. 更好的错误处理:在 Supabase 之前检测问题可以实现自动重试逻辑,这对于透明地处理 iOS 缓存问题至关重要。

如果验证失败,函数会自动:

  1. 退出 Google 登录(清除缓存的 token - 在 iOS 上至关重要)
  2. 重试一次身份验证(强制使用正确的 nonce 生成新 token)
  3. 如果重试仍然失败,则返回错误

最后,将验证后的 token 发送到 Supabase:

const { data, error } = await supabase.auth.signInWithIdToken({
provider: 'google',
token: googleResponse.idToken,
nonce: rawNonce, // Pass the raw (unhashed) nonce
});

完整实现可在 示例应用的 supabaseAuthUtils.ts 文件,包含以下内容:

  • getUrlSafeNonce() - 生成 URL 安全的随机 nonce
  • sha256Hash() - 使用 SHA-256 对字符串进行哈希处理
  • getNonce() - 生成 nonce 对
  • decodeJWT() - 解码 JWT token
  • validateJWTToken() - 验证 JWT 的 audience 和 nonce
  • authenticateWithGoogleSupabase() - 具备自动重试机制的主认证函数

请根据您的目标平台,查看相应的配置指南:

如果你正在使用 Supabase Google Login - 常规设置 规划身份验证和账户流程,并将它与 使用 @capgo/capacitor-social-login 了解使用 @capgo/capacitor-social-login 时的原生能力, @capgo/capacitor-social-login 了解 @capgo/capacitor-social-login 中的实现细节, @capgo/capacitor-passkey 了解 @capgo/capacitor-passkey 中的实现细节, @capgo/capacitor-native-biometric 了解 @capgo/capacitor-native-biometric 中的实现细节,以及 双重身份验证 了解双因素认证中的实现细节。