原创

Google (Gmail) Login 对接配置指南


1. 前提条件

  • 一个 Google 账号(Gmail)
  • 项目已部署或本地运行于 http://localhost:3000
  • 已配置 NEXTAUTH_URL 和 NEXTAUTH_SECRET 环境变量

2. 创建 Google Cloud 项目

  1. 访问 Google Cloud Console
  2. 点击顶部项目选择器 → New Project(新建项目)
  3. 填写项目信息:
    • Project nameFlexes(或你喜欢的名称)
    • Organization:选择你的组织(个人账号可留空)
  4. 点击 Create(创建)
  5. 确保新建的项目已被选中(顶部项目选择器)

💡 直达链接:https://console.cloud.google.com/projectcreate


3. 配置 OAuth 同意屏幕

在创建凭据之前,必须先配置 OAuth 同意屏幕(用户授权时看到的页面)。

3.1 进入同意屏幕配置

  1. 左侧菜单 → APIs & Services → OAuth consent screen
  2. 或直达:https://console.cloud.google.com/apis/credentials/consent

3.2 选择 User Type

类型说明适用场景
Internal(内部)仅限组织内的 Google Workspace 用户企业内部应用
External(外部)所有 Google 用户✅ Flexes 应选择此项

选择 External,点击 Create

3.3 填写 App 信息

字段说明
App nameFlexes用户在授权页面看到的名称
User support email你的邮箱用户遇到问题时联系的邮箱
App logo(可选)上传 Logo显示在授权页面
App domain
- Application home pagehttps://flexes.work应用主页
- Application privacy policyhttps://flexes.work/privacy隐私政策页面
- Application terms of servicehttps://flexes.work/terms服务条款页面
Authorized domainsflexes.work授权域名
Developer contact email你的邮箱Google 联系你的邮箱

点击 Save and Continue

3.4 配置 Scopes(权限范围)

  1. 点击 Add or Remove Scopes
  2. 勾选以下 scope:
Scope说明
.../auth/userinfo.email获取用户邮箱
.../auth/userinfo.profile获取用户基本资料
openidOpenID Connect 标准
  1. 点击 Update → Save and Continue

这些都是非敏感权限,不需要 Google 额外审核。

3.5 添加测试用户(开发阶段)

在 App 发布之前(Testing 状态),只有添加到测试列表的用户才能登录:

  1. 点击 Add Users
  2. 输入测试用的 Gmail 地址
  3. 点击 Save and Continue

最多可以添加 100 个测试用户。

3.6 完成配置

检查摘要页面信息,点击 Back to Dashboard


4. 创建 OAuth 2.0 凭据

4.1 进入凭据页面

  1. 左侧菜单 → APIs & Services → Credentials
  2. 或直达:https://console.cloud.google.com/apis/credentials

4.2 创建凭据

  1. 点击顶部 + CREATE CREDENTIALS → OAuth client ID
  2. 填写信息:
字段
Application typeWeb application
NameFlexes Web Client
Authorized JavaScript origins见下方
Authorized redirect URIs见下方

Authorized JavaScript origins(授权来源)

环境URI
本地开发http://localhost:3000
生产环境https://flexes.work

Authorized redirect URIs(授权重定向 URI)

环境URI
本地开发http://localhost:3000/api/auth/callback/google
生产环境https://flexes.work/api/auth/callback/google
  1. 点击 Create

4.3 获取凭据

创建成功后弹出对话框,显示:

  • Client ID → 即 GOOGLE_CLIENT_ID(格式:xxxx.apps.googleusercontent.com
  • Client Secret → 即 GOOGLE_CLIENT_SECRET

💡 也可以随时在 Credentials 页面点击已创建的客户端查看。

⚠️ Client Secret 不要提交到 Git 或暴露在前端代码中。


5. 配置项目环境变量

将获取的值填入项目的 .env.local(或 .env)文件中:

# --- Google OAuth ---
GOOGLE_CLIENT_ID="xxxxxxxxxxxx.apps.googleusercontent.com"
GOOGLE_CLIENT_SECRET="GOCSPX-xxxxxxxxxxxxxxxx"

已有代码说明

项目中 Google OAuth Provider 已完成配置,无需修改代码:

src/lib/auth-options.ts

Google({
clientId: process.env.GOOGLE_CLIENT_ID ?? "",
clientSecret: process.env.GOOGLE_CLIENT_SECRET ?? "",
allowDangerousEmailAccountLinking: true,
profile(profile) {
return {
id: profile.sub,
name: profile.name,
email: profile.email,
image: profile.picture,
role: "CANDIDATE", // default role for OAuth
};
},
}),
  • 通过 Google 登录的新用户默认角色为 CANDIDATE
  • allowDangerousEmailAccountLinking: true 允许相同邮箱的账号自动关联(如用户先用邮箱注册,后用 Google 登录)

6. 回调 URL 配置

NextAuth.js v5 使用标准的 OAuth 回调路径:

环境Authorized redirect URI
本地开发http://localhost:3000/api/auth/callback/google
生产环境https://flexes.work/api/auth/callback/google

⚠️ 回调 URL 必须精确匹配,包括协议、域名、端口和路径。末尾不要加斜杠。


7. 权限与数据说明

请求的权限(Scopes)

Scope说明敏感级别
openidOpenID Connect 标识非敏感
email用户邮箱地址非敏感
profile用户基本信息(姓名、头像)非敏感

所有权限均为非敏感级别,不需要 Google 额外审核

项目使用的用户数据

Google 字段存储到说明
profile.subUser.providerIdGoogle 用户唯一 ID
profile.nameUser.name用户姓名
profile.emailUser.emailGmail 邮箱
profile.pictureUser.avatarUrlGoogle 头像 URL

8. 测试流程

8.1 开发模式限制

Google OAuth App 默认处于 Testing(测试) 状态:

  • ✅ 在同意屏幕中添加的测试用户可以登录
  • ❌ 其他 Google 用户登录时会看到 "This app isn't verified" 警告
  • ❌ 未添加的用户无法完成授权

8.2 测试步骤

  1. 确保你的 Gmail 地址已添加到同意屏幕的测试用户列表
  2. 启动本地开发服务器:pnpm dev
  3. 访问 http://localhost:3000/login
  4. 点击 Continue with Google 按钮
  5. 浏览器跳转到 Google 授权页面:
    • 选择 Google 账号
    • 查看权限请求并点击 Allow(允许)
    • 测试阶段可能显示 "This app isn't verified" 页面,点击 Continue 即可
  6. 授权成功后自动跳回 Flexes 并完成登录:
    • 新用户:自动创建账号(角色 = CANDIDATE)并创建候选人资料
    • 已有用户:直接登录
  7. 验证:
    • 检查数据库 User 表,确认 provider = "google" 和 providerId 已填充
    • 确认 Candidate 表已创建对应记录
    • 确认头像已正确显示(来源:lh3.googleusercontent.com

8.3 绕过 "This app isn't verified" 警告

在测试阶段,授权页面会显示安全警告:

  1. 点击 Advanced(高级)
  2. 点击 Go to Flexes (unsafe)
  3. 正常完成授权

此警告仅在 Testing 状态出现,发布后不再显示。


9. 正式上线(发布 App)

要让所有 Google 用户都能无警告地使用 Google Login:

9.1 准备清单

项目要求状态
隐私政策页面https://flexes.work/privacy必须
服务条款页面https://flexes.work/terms推荐
App Logo上传到同意屏幕设置推荐
域名验证在 Google Search Console 中验证域名所有权必须
HTTPS生产环境必须使用 HTTPS必须

9.2 验证域名

  1. 访问 Google Search Console
  2. 添加域名 flexes.work
  3. 通过 DNS TXT 记录验证所有权
  4. 验证成功后,回到 OAuth 同意屏幕的 Authorized domains 中添加 flexes.work

9.3 发布 App

  1. 进入 OAuth consent screen
  2. 点击 PUBLISH APP(发布应用)
  3. 确认发布

ℹ️ 由于我们只使用非敏感权限(email、profile、openid),发布时不需要提交 Google 审核,点击发布后立即生效。

9.4 更新生产环境凭据

确保生产环境的 redirect URI 已添加到 Google Cloud Console:

https://flexes.work/api/auth/callback/google

10. 常见问题排查

问题:点击 Google 登录后出现 "redirect_uri_mismatch" 错误

原因:回调 URL 不匹配。

解决

  1. 进入 Google Cloud Console → Credentials → 点击 OAuth Client
  2. 确认 Authorized redirect URIs 中包含:
    • 开发:http://localhost:3000/api/auth/callback/google
    • 生产:https://flexes.work/api/auth/callback/google
  3. 注意:修改后可能需要等几分钟生效

问题:显示 "Access blocked: This app's request is invalid" (Error 400)

原因:通常是 Authorized JavaScript origins 缺少当前域名。

解决

  1. 添加 http://localhost:3000 到 Authorized JavaScript origins
  2. 生产环境添加 https://flexes.work

问题:显示 "This app isn't verified"

原因:OAuth App 仍处于 Testing 状态。

解决

  • 测试阶段:点击 Advanced → Go to Flexes (unsafe) 继续
  • 正式使用:在 OAuth consent screen 中点击 PUBLISH APP 发布

问题:登录后头像无法显示

原因:Content Security Policy (CSP) 未允许 Google 头像域名。

解决:项目的 next.config.ts 已配置了 lh3.googleusercontent.com

images: {
remotePatterns: [
{ protocol: "https", hostname: "lh3.googleusercontent.com" },
],
},

如果头像仍不显示,检查 CSP 的 img-src 是否包含该域名。


问题:GOOGLE_CLIENT_ID 或 GOOGLE_CLIENT_SECRET 未生效

解决

  1. 检查 .env.local(优先于 .env)中是否正确设置
  2. Client ID 格式应为:xxxx.apps.googleusercontent.com
  3. Client Secret 格式应为:GOCSPX-xxxx
  4. 重启开发服务器(Ctrl+C → pnpm dev

问题:Google 登录按钮点击无反应

解决

  1. 确认 GOOGLE_CLIENT_ID 和 GOOGLE_CLIENT_SECRET 已正确设置
  2. 确认 NEXTAUTH_URL 与当前访问地址一致
  3. 检查浏览器控制台是否有 JavaScript 错误

环境变量汇总

# .env.local 或 .env
GOOGLE_CLIENT_ID="123456789-xxxxxxxx.apps.googleusercontent.com" # Google OAuth Client ID
GOOGLE_CLIENT_SECRET="GOCSPX-xxxxxxxxxxxxxxxx" # Google OAuth Client Secret
NEXTAUTH_URL="http://localhost:3000" # 开发环境
# NEXTAUTH_URL="https://flexes.work" # 生产环境
NEXTAUTH_SECRET="your-random-secret" # NextAuth 加密密钥

相关文件

文件说明
src/lib/auth-options.tsGoogle Provider 配置(第 59-72 行)
src/lib/auth.tsNextAuth 主配置,包含 OAuth signIn 回调
src/components/auth/login-form.tsx登录页 Google 按钮
src/components/auth/register-form.tsx注册页 Google 按钮
next.config.ts图片域名白名单(Google 头像)
.env.example环境变量模板
正文到此结束
Loading...