Google 登录集成教程(Web + Expo 移动端)

本教程适用于 Next.js 后端 + Expo 移动端的 Google OAuth 登录集成。


一、Google Cloud Console 配置

1.1 创建项目

  1. 访问 Google Cloud Console
  2. 点击"新建项目",输入项目名称后创建

1.2 配置 OAuth 同意屏幕

⚠️ 重要:必须先配置同意屏幕,否则无法创建 OAuth 客户端 ID

  1. 进入 API 和服务 → OAuth 同意屏幕
  2. 点击 "Get started" 按钮
  3. 填写 App Information :
    • App name:填写你的应用名称
    • User support email:选择你的邮箱
  4. 点击 "Next"
  5. Audience 页面直接点击 "Next"
  6. Contact Information 填写你的邮箱,点击 "Next"
  7. Finish 页面点击 "Create"
  8. 创建完成后,点击左侧 "Audience",添加测试用户(你的邮箱)

1.3 创建 OAuth 客户端 ID

⚠️ 关键 :需要创建 4 个不同的客户端 ID,分别用于 Web、Android、iOS 和 Expo Go 调试

进入 API 和服务 → 凭据 → 创建凭据 → OAuth 客户端 ID

A. Web 应用(后端用)
  • 应用类型:Web 应用

  • 已获授权的重定向 URI:

    复制代码
    http://localhost:3000/api/auth/callback/google
    https://你的域名/api/auth/callback/google
  • 记录生成的 Client ID 和 Client Secret,后续配置到后端环境变量

B. Android 客户端

⚠️ 最容易出错的地方:必须使用正确的 SHA-1 指纹,且必须开启自定义 URI scheme

  • 应用类型:Android

  • 包名 :填写你的 Android 包名(如 com.yourcompany.yourapp)

  • SHA-1 证书指纹:

    • 从 Expo EAS Dashboard 获取 → 进入项目 → Credentials → Android → Upload keystore → 复制 SHA-1 Fingerprint
    • 格式示例:42:DA:B6:72:B1:F1:0C:69:BA:13:73:E8:6E:8B:0B:F8:C0:A4:4C:6C

    ⚠️ 注意:

    • 不要使用 debug.keystore 的指纹
    • 如果重新生成 keystore,必须更新这里的指纹
  • 创建后必须执行:

    1. 点击刚创建的 Android 客户端
    2. 点击 Advanced settings
    3. 开启 Enable custom URI scheme

    ⚠️ 必须开启 :否则会报错 Custom URI scheme is not enabled for your Android client

  • 记录生成的 Client ID

C. iOS 客户端(如需要)
  • 应用类型:iOS
  • Bundle ID :填写你的 iOS Bundle ID(如 com.yourcompany.yourapp)
  • 记录生成的 Client ID
D. Expo Web / Proxy(仅用于 Expo Go 调试)
  • 应用类型:Web 应用

  • 已获授权的重定向 URI:

    复制代码
    https://auth.expo.io/@你的expo用户名/你的项目slug

    💡 提示:在 app.json 中查看 owner 和 slug 字段

  • 记录生成的 Client ID 和 Client Secret


二、后端配置

2.1 环境变量配置

在后端项目的 .env 文件中添加:

env 复制代码
# Web 应用凭据
GOOGLE_CLIENT_ID=你的Web客户端ID
GOOGLE_CLIENT_SECRET=你的Web客户端Secret

# 移动端客户端 ID(用于验证 token)
GOOGLE_ANDROID_CLIENT_ID=你的Android客户端ID
GOOGLE_IOS_CLIENT_ID=你的iOS客户端ID
GOOGLE_EXPO_CLIENT_ID=你的Expo客户端ID

2.2 生产环境配置

如果使用 Vercel 部署:

  1. 进入项目设置 → Environment Variables
  2. 添加上述所有环境变量

三、移动端配置

3.1 环境变量配置

在移动端项目的 .env 文件中添加:

env 复制代码
EXPO_PUBLIC_API_URL=http://10.0.2.2:3000
EXPO_PUBLIC_GOOGLE_ANDROID_CLIENT_ID="你的Android客户端ID"
EXPO_PUBLIC_GOOGLE_IOS_CLIENT_ID="你的iOS客户端ID"
EXPO_PUBLIC_GOOGLE_EXPO_CLIENT_ID="你的Expo客户端ID"
EXPO_PUBLIC_GOOGLE_WEB_CLIENT_ID="你的Expo客户端ID"

💡 提示:10.0.2.2 是 Android 模拟器访问本机的地址

3.2 app.json 配置

⚠️ 关键配置:必须正确配置 intentFilters,否则 Google 回调无法返回 App

json 复制代码
{
  "expo": {
    "scheme": "yourappscheme",
    "android": {
      "package": "com.yourcompany.yourapp",
      "intentFilters": [
        {
          "action": "VIEW",
          "category": ["BROWSABLE", "DEFAULT"],
          "data": [
            {
              "scheme": "com.googleusercontent.apps.你的Android客户端ID的数字部分",
              "path": "/oauth2redirect"
            }
          ]
        }
      ]
    }
  }
}

💡 提示:scheme 的格式为 com.googleusercontent.apps. + Android Client ID 的数字部分(去掉 .apps.googleusercontent.com)

3.3 登录页面代码

在 app/(auth)/sign-in.tsx 中:

typescript 复制代码
import * as Google from "expo-auth-session/providers/google";
import { makeRedirectUri, ResponseType } from "expo-auth-session";
import Constants from "expo-constants";

// 判断是否在 Expo Go 环境
const isExpoGo = Constants.appOwnership === "expo";

// 配置 redirectUri
const redirectUri = useMemo(() => {
  if (isExpoGo) {
    // Expo Go 环境使用代理
    return makeRedirectUri({ useProxy: true, path: "oauthredirect" });
  }
  // Development Build / 正式包使用自定义 scheme
  const googleScheme = "com.googleusercontent.apps.你的Android客户端ID的数字部分";
  return makeRedirectUri({
    scheme: googleScheme,
    path: "oauth2redirect",
    native: `${googleScheme}:/oauth2redirect`
  });
}, [isExpoGo]);

// 配置 Google 登录
const [googleRequest, googleResponse, promptGoogleSignIn] = Google.useAuthRequest({
  expoClientId: isExpoGo ? expoClientId ?? undefined : undefined,
  androidClientId: Platform.OS === "android" ? androidClientId ?? undefined : undefined,
  iosClientId: Platform.OS === "ios" ? iosClientId ?? undefined : undefined,
  webClientId: webClientId ?? undefined,
  responseType: ResponseType.Code,
  usePKCE: true,
  shouldAutoExchangeCode: false,
  redirectUri,
  scopes: ["openid", "email", "profile"]
});

// 处理登录响应
useEffect(() => {
  if (googleResponse?.type === "success") {
    const { code, codeVerifier } = googleResponse.params;
    // 发送到后端验证
    // ...
  }
}, [googleResponse]);

3.4 创建回调路由

⚠️ 必须创建:否则回调会落在 Unmatched Route 页面

创建 app/oauth2redirect.tsx:

typescript 复制代码
import { useEffect } from "react";
import * as WebBrowser from "expo-web-browser";

export default function OAuthRedirectScreen() {
  useEffect(() => {
    WebBrowser.maybeCompleteAuthSession();
  }, []);

  return null;
}

四、构建与验证

⚠️ 重要:Expo Go 无法测试 Google 登录,必须使用 Development Build

4.1 为什么需要 Development Build?

Expo Go 的回调 URL(exp://...)会被 Google Console 拒绝,因此必须构建真实的 APK/IPA 才能测试。

4.2 构建流程

  1. 生成 Development Build

    bash 复制代码
    eas build --profile development --platform android

    ⏱️ 构建时间约 20 分钟,请耐心等待

  2. 删除旧版本 App

    ⚠️ 必须删除:否则新的 intentFilters 不会生效

    在手机上卸载旧版本的 App

  3. 安装新构建的 APK

    从 EAS Dashboard 下载 APK 并安装到手机

  4. 启动开发服务器

    bash 复制代码
    npx expo start --dev-client

4.3 验证配置

验证回调是否注册成功
bash 复制代码
adb shell cmd package resolve-activity \
  -d "com.googleusercontent.apps.你的Android客户端ID的数字部分:/oauth2redirect" \
  -a android.intent.action.VIEW

预期输出 :应包含你的包名和 .MainActivity,例如:

复制代码
com.yourcompany.yourapp/.MainActivity

如果未找到:说明安装的仍是旧 APK,请重新卸载并安装新版本

验证 APK 签名(可选)
bash 复制代码
$ANDROID_HOME/build-tools/36.0.0/apksigner verify --print-certs dev-client.apk

检查 :SHA-1 digest 应与 Google Console 中登记的一致


五、授权流程说明

  1. 客户端使用 expo-auth-session/providers/google 发起授权请求(responseType=code,PKCE 自动开启)
  2. 用户在浏览器中选择 Google 账号
  3. Google 重定向到自定义 scheme:
    • Development Build:com.googleusercontent.apps.xxx:/oauth2redirect
    • Expo Go:https://auth.expo.io/...
  4. 客户端获取 authorizationCode 和 codeVerifier
  5. 客户端将 code 和 verifier 发送给后端
  6. 后端使用对应的 Client ID 向 Google 交换 id_token
  7. 后端验证 token 并创建会话

💡 提示:授权完成后浏览器不会自动关闭,可手动返回 App。关键是确认终端日志打印 Google auth response success


六、常见问题排查

现象 原因 解决方案
400 错误:redirect_uri 为 exp://... 仍在 Expo Go 环境 使用 Development Build
400 错误:Custom URI scheme is not enabled Android 客户端未开启自定义 URI 在 Google Console 中开启 Enable custom URI scheme
浏览器完成登录但无回调 intentFilters 未注册 使用 adb resolve-activity 检查;重新安装 Dev Client
后端交换 token 失败 环境变量缺失或错误 检查 GOOGLE_*_CLIENT_ID 是否齐全且正确
SHA-1 指纹不匹配 使用了错误的 keystore 从 EAS Dashboard 获取正确的 SHA-1 并更新到 Google Console

七、重要提醒

  1. Keystore 管理:如果重新生成 keystore,必须同步更新 Google Console 中的 SHA-1 指纹
  2. 环境变量同步:后端和移动端的 Client ID 必须一一对应
  3. 测试用户:开发阶段记得在 OAuth 同意屏幕中添加测试用户
  4. 回调验证 :每次重新构建后,务必使用 adb resolve-activity 验证回调是否注册成功

八、调试技巧

  1. 查看终端日志 :确认是否打印 Google auth response success
  2. 检查 redirectUri :在代码中打印 redirectUri 确认格式正确
  3. 验证 Client ID :确认传递给 useAuthRequest 的 Client ID 与平台匹配
  4. 测试回调 :使用 adb shell am start 手动触发回调测试

完成以上配置后,即可实现 Web 端和移动端的 Google 登录功能。

相关推荐
代码猎人1 小时前
前端怎么优化页面性能
前端
代码猎人1 小时前
前端怎么配合后端完成数据对接
前端
lexiangqicheng2 小时前
Docker的沙箱机制是怎样的?
前端·javascript
燕落南枝2 小时前
HTML 表格标签与 AI 合并单元格实战指南
前端·人工智能·html
zyseo82 小时前
谷歌SEO 内链地图脚本:Python 画出权重分发,揪出孤岛页
java·前端·python
ClickHouseDB3 小时前
ClickHouse .NET 驱动程序新特性:从 1.0 到 1.3 的演进之路
java·前端·windows
bitbrowser3 小时前
Gmail注册要求手机号如何解决?哪些情况可以不填手机号
前端·指纹浏览器·gmail
LCG米3 小时前
STM32 HardFault故障定位实测:压栈帧寄存器解析、CFSR故障源判读与出错地址回溯
前端·javascript·stm32·单片机·嵌入式
夏幻灵3 小时前
Express 静态资源托管详解:从本地 HTML 到 express.static()
前端·html·express