/login 和 /register 上的”用 Google 登录”按钮,在 GOOGLE_CLIENT_ID 和
GOOGLE_CLIENT_SECRET 配好后会自动显示。你不用写一行 provider 代码——OAuth 流程
Better Auth 包办了,src/lib/auth.ts 的自动合并逻辑会把 Google 登录和已有的
邮箱账号挂钩。
前置条件
- 一个 Google 账号。
- 决定好生产域名(先在本地开发也行)。
- 10 分钟——大半是填 OAuth 同意页。
一步步配置
- 打开 Google Cloud Console:console.cloud.google.com, 建一个(或选一个)项目。每个产品一个项目最干净。
-
配置 OAuth 同意页。APIs & Services → OAuth consent screen,用户类型选
“External”。填上应用名、支持邮箱、Logo。需要的 scope 就是默认的:
userinfo.email、userinfo.profile、openid。把生产域名加为 authorized domain。 - 创建 OAuth 2.0 凭证。APIs & Services → Credentials → Create Credentials → OAuth client ID。应用类型:Web application。
-
填回调 URI。Better Auth 的回调路径是
/api/auth/callback/google。本地和 生产都加上:如果用 Vercel preview,preview URL 也加上。 -
把 client ID + secret 写到
.env.local: -
打开按钮开关。
src/config/site.ts: -
重启 dev server。环境变量是启动时读的——每次改完
.env.local都要重跑pnpm dev。
背后发生了什么
用户点”用 Google 登录”,会跑authClient.signIn.social({ provider: 'google', callbackURL: '/dashboard' })。Better Auth 跳到 Google,Google 回调到
/api/auth/callback/google,回调 handler 干这些事:
- 用授权码换 access token + ID token。
- 在
account里按providerId = 'google'查邮箱,命中就登。 - 没命中但邮箱在
user里有,就插一行新的account关联(受信任 provider 的 账号合并默认开——见src/lib/auth.ts)。 - 完全没命中,建新的
user+account,触发 post-create 钩子(送注册礼积分, 命中ADMIN_EMAILS的话提为 admin)。
[better-auth] 前缀的日志。
验证是否生效
- 访问
/login——“用 Google 登录”按钮应该出现。 - 点一下,跳到
accounts.google.com,选账号,落回/dashboard。 - 看
account表——应该有一行providerId = 'google',挂在你的user行下。 - 退出再用 Google 登一次。同一个
user.id,不会多一行。 - 看
user.image,应该是 Google 头像 URL。
常见坑
redirect_uri_mismatch报错。Google 控制台里回调 URI 写错了。末尾的斜杠 要紧,httpvshttps要紧,localhost 端口要紧。从上面的列表里复制粘贴。- 本地能用、生产不行。你只加了本地的 URI。把生产 URI 加到同一个 OAuth client 里(一个 client 可以有多个回调 URI)。
- 加完 URI 没立刻生效。Google 那边偶尔会有几分钟的传播延迟。等等再试,别急着改别的。
- OAuth 同意页一直”Testing”状态。在 Testing 状态下,只有列表里的 test user 能登。点 Publish App 才能对外开放。除非你要敏感 scope,否则通常不用走 verification(敏感 scope 的 verification 周期是几周起步)。
NEXT_PUBLIC_GOOGLE_CLIENT_ID没配。One-Tap 会静默不工作。见 One-Tap 文档。- dev / preview / prod 域名不同。每个都得单独加回调 URI 条目,没有通配符。
- 没拿到 refresh token。Better Auth 默认走
online模式——单纯登录够用。 如果以后要在用户身份下调 Google API,需要 offline access 和 refresh token, 得在 provider 配置里加accessType: 'offline'。
官方文档
- 用 OAuth 2.0 做 Web 应用 — developers.google.com/identity/protocols/oauth2/web-server
- OAuth 同意页设置 — support.google.com/cloud/answer/10311615
- Better Auth Google provider — better-auth.com/docs/authentication/google