> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vibestrap.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Google OAuth

> 在 Google Cloud 建一个 OAuth 2.0 Client，配两个环境变量，"用 Google 登录"按钮就亮了。

`/login` 和 `/register` 上的"用 Google 登录"按钮，在 `GOOGLE_CLIENT_ID` 和
`GOOGLE_CLIENT_SECRET` 配好后会自动显示。你不用写一行 provider 代码——OAuth 流程
Better Auth 包办了，`src/lib/auth.ts` 的自动合并逻辑会把 Google 登录和已有的
邮箱账号挂钩。

## 前置条件

* 一个 Google 账号。
* 决定好生产域名（先在本地开发也行）。
* 10 分钟——大半是填 OAuth 同意页。

## 一步步配置

1. **打开 Google Cloud Console**：[console.cloud.google.com](https://console.cloud.google.com)，
   建一个（或选一个）项目。每个产品一个项目最干净。

2. **配置 OAuth 同意页**。APIs & Services → OAuth consent screen，用户类型选
   "External"。填上应用名、支持邮箱、Logo。需要的 scope 就是默认的：
   `userinfo.email`、`userinfo.profile`、`openid`。把生产域名加为 authorized domain。

3. **创建 OAuth 2.0 凭证**。APIs & Services → Credentials → Create Credentials →
   OAuth client ID。应用类型：**Web application**。

4. **填回调 URI**。Better Auth 的回调路径是 `/api/auth/callback/google`。本地和
   生产都加上：

   ```
   http://localhost:3000/api/auth/callback/google
   https://your-domain.com/api/auth/callback/google
   ```

   如果用 Vercel preview，preview URL 也加上。

5. **把 client ID + secret 写到 `.env.local`：**

   ```bash theme={null}
   GOOGLE_CLIENT_ID=1234567890-abc...apps.googleusercontent.com
   GOOGLE_CLIENT_SECRET=GOCSPX-...
   # 镜像一份给客户端 One-Tap 用（见 /docs/auth/one-tap）
   NEXT_PUBLIC_GOOGLE_CLIENT_ID=1234567890-abc...apps.googleusercontent.com
   ```

6. **打开按钮开关**。`src/config/site.ts`：

   ```ts theme={null}
   features: { enableGoogleLogin: true, /* ... */ }
   ```

7. **重启 dev server**。环境变量是启动时读的——每次改完 `.env.local` 都要重跑 `pnpm dev`。

## 背后发生了什么

用户点"用 Google 登录"，会跑 `authClient.signIn.social({ provider: 'google',
callbackURL: '/dashboard' })`。Better Auth 跳到 Google，Google 回调到
`/api/auth/callback/google`，回调 handler 干这些事：

1. 用授权码换 access token + ID token。
2. 在 `account` 里按 `providerId = 'google'` 查邮箱，命中就登。
3. 没命中但邮箱在 `user` 里有，就插一行新的 `account` 关联（受信任 provider 的
   账号合并默认开——见 `src/lib/auth.ts`）。
4. 完全没命中，建新的 `user` + `account`，触发 post-create 钩子（送注册礼积分，
   命中 `ADMIN_EMAILS` 的话提为 admin）。

dev console 可以看到全过程——Better Auth 每一步都有 `[better-auth]` 前缀的日志。

## 验证是否生效

1. 访问 `/login`——"用 Google 登录"按钮应该出现。
2. 点一下，跳到 `accounts.google.com`，选账号，落回 `/dashboard`。
3. 看 `account` 表——应该有一行 `providerId = 'google'`，挂在你的 `user` 行下。
4. 退出再用 Google 登一次。同一个 `user.id`，不会多一行。
5. 看 `user.image`，应该是 Google 头像 URL。

## 常见坑

* **`redirect_uri_mismatch` 报错**。Google 控制台里回调 URI 写错了。末尾的斜杠
  要紧，`http` vs `https` 要紧，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 文档](/zh/auth/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](https://developers.google.com/identity/protocols/oauth2/web-server)
* OAuth 同意页设置 — [support.google.com/cloud/answer/10311615](https://support.google.com/cloud/answer/10311615)
* Better Auth Google provider — [better-auth.com/docs/authentication/google](https://www.better-auth.com/docs/authentication/google)
