http://localhost:3000NEXTAUTH_URL 和 NEXTAUTH_SECRET 环境变量Flexes(或你喜欢的名称)
在创建凭据之前,必须先配置 OAuth 同意屏幕(用户授权时看到的页面)。

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

| 字段 | 值 | 说明 |
|---|---|---|
| App name | Flexes | 用户在授权页面看到的名称 |
| User support email | 你的邮箱 | 用户遇到问题时联系的邮箱 |
| App logo | (可选)上传 Logo | 显示在授权页面 |
| App domain | ||
| - Application home page | https://flexes.work | 应用主页 |
| - Application privacy policy | https://flexes.work/privacy | 隐私政策页面 |
| - Application terms of service | https://flexes.work/terms | 服务条款页面 |
| Authorized domains | flexes.work | 授权域名 |
| Developer contact email | 你的邮箱 | Google 联系你的邮箱 |
点击 Save and Continue。
| Scope | 说明 |
|---|---|
.../auth/userinfo.email | 获取用户邮箱 |
.../auth/userinfo.profile | 获取用户基本资料 |
openid | OpenID Connect 标准 |
这些都是非敏感权限,不需要 Google 额外审核。
在 App 发布之前(Testing 状态),只有添加到测试列表的用户才能登录:
最多可以添加 100 个测试用户。
检查摘要页面信息,点击 Back to Dashboard。

| 字段 | 值 |
|---|---|
| Application type | Web application |
| Name | Flexes Web Client |
| Authorized JavaScript origins | 见下方 |
| Authorized redirect URIs | 见下方 |

| 环境 | URI |
|---|---|
| 本地开发 | http://localhost:3000 |
| 生产环境 | https://flexes.work |
| 环境 | URI |
|---|---|
| 本地开发 | http://localhost:3000/api/auth/callback/google |
| 生产环境 | https://flexes.work/api/auth/callback/google |
创建成功后弹出对话框,显示:
GOOGLE_CLIENT_ID(格式:xxxx.apps.googleusercontent.com)GOOGLE_CLIENT_SECRET💡 也可以随时在 Credentials 页面点击已创建的客户端查看。
⚠️ Client Secret 不要提交到 Git 或暴露在前端代码中。
将获取的值填入项目的 .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
};
},
}),
CANDIDATEallowDangerousEmailAccountLinking: true 允许相同邮箱的账号自动关联(如用户先用邮箱注册,后用 Google 登录)NextAuth.js v5 使用标准的 OAuth 回调路径:
| 环境 | Authorized redirect URI |
|---|---|
| 本地开发 | http://localhost:3000/api/auth/callback/google |
| 生产环境 | https://flexes.work/api/auth/callback/google |
⚠️ 回调 URL 必须精确匹配,包括协议、域名、端口和路径。末尾不要加斜杠。
| Scope | 说明 | 敏感级别 |
|---|---|---|
openid | OpenID Connect 标识 | 非敏感 |
email | 用户邮箱地址 | 非敏感 |
profile | 用户基本信息(姓名、头像) | 非敏感 |
所有权限均为非敏感级别,不需要 Google 额外审核。
| Google 字段 | 存储到 | 说明 |
|---|---|---|
profile.sub | User.providerId | Google 用户唯一 ID |
profile.name | User.name | 用户姓名 |
profile.email | User.email | Gmail 邮箱 |
profile.picture | User.avatarUrl | Google 头像 URL |
Google OAuth App 默认处于 Testing(测试) 状态:
pnpm devhttp://localhost:3000/loginUser 表,确认 provider = "google" 和 providerId 已填充Candidate 表已创建对应记录lh3.googleusercontent.com)在测试阶段,授权页面会显示安全警告:
此警告仅在 Testing 状态出现,发布后不再显示。
要让所有 Google 用户都能无警告地使用 Google Login:
| 项目 | 要求 | 状态 |
|---|---|---|
| 隐私政策页面 | https://flexes.work/privacy | 必须 |
| 服务条款页面 | https://flexes.work/terms | 推荐 |
| App Logo | 上传到同意屏幕设置 | 推荐 |
| 域名验证 | 在 Google Search Console 中验证域名所有权 | 必须 |
| HTTPS | 生产环境必须使用 HTTPS | 必须 |
flexes.workflexes.workℹ️ 由于我们只使用非敏感权限(email、profile、openid),发布时不需要提交 Google 审核,点击发布后立即生效。
确保生产环境的 redirect URI 已添加到 Google Cloud Console:
https://flexes.work/api/auth/callback/google
原因:回调 URL 不匹配。
解决:
http://localhost:3000/api/auth/callback/googlehttps://flexes.work/api/auth/callback/google原因:通常是 Authorized JavaScript origins 缺少当前域名。
解决:
http://localhost:3000 到 Authorized JavaScript originshttps://flexes.work原因:OAuth App 仍处于 Testing 状态。
解决:
原因: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 未生效解决:
.env.local(优先于 .env)中是否正确设置xxxx.apps.googleusercontent.comGOCSPX-xxxxCtrl+C → pnpm dev)解决:
GOOGLE_CLIENT_ID 和 GOOGLE_CLIENT_SECRET 已正确设置NEXTAUTH_URL 与当前访问地址一致# .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.ts | Google Provider 配置(第 59-72 行) |
src/lib/auth.ts | NextAuth 主配置,包含 OAuth signIn 回调 |
src/components/auth/login-form.tsx | 登录页 Google 按钮 |
src/components/auth/register-form.tsx | 注册页 Google 按钮 |
next.config.ts | 图片域名白名单(Google 头像) |
.env.example | 环境变量模板 |