Google 提供者的设置和使用。
获取 Google 凭据
要将 Google 用作社交身份提供者,你需要获取 Google 凭据。你可以在 Google Cloud Console 中创建一个新项目来获取这些凭据。
在 Google Cloud Console > 凭据 > 授权重定向 URI 中,请确保将重定向 URL 设置为 http://localhost:3000/api/auth/callback/google 用于本地开发。生产环境中,请将重定向 URL 设置为你的应用程序域名,例如 https://example.com/api/auth/callback/google。如果修改了认证路由的基本路径,请相应更新重定向 URL。
创建你的 Google OAuth 凭据
如果你尚未创建 OAuth 凭据,请按照以下逐步说明操作:
- 打开 Google Cloud Console → API 与服务 → 凭据
- 点击 创建凭据 → OAuth 客户端 ID
- 选择 Web 应用程序
- 添加你的重定向 URI:
http://localhost:3000/api/auth/callback/google(用于本地开发)https://your-domain.com/api/auth/callback/google(用于生产环境)
- 将 客户端 ID 和 客户端密钥 复制到你的环境变量中
这些步骤可以避免 redirect_uri_mismatch 等常见问题。
配置提供者
要配置该提供者,需要将 clientId 和 clientSecret 传递给 socialProviders.google。
import { betterAuth } from "better-auth"
export const auth = betterAuth({
baseURL: process.env.BETTER_AUTH_URL,
socialProviders: {
google: {
clientId: process.env.GOOGLE_CLIENT_ID as string,
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
},
},
})重要:设置你的基础 URL
你必须配置 baseURL 以避免 redirect_uri_mismatch 错误。Better Auth 使用它来构造发送给 Google 的 OAuth 回调 URL。
选项 1:使用环境变量(推荐)
在 .env 文件中添加:
BETTER_AUTH_URL=https://your-domain.com选项 2:显式配置
如上所示,直接将 baseURL 传递到认证配置中。
如果不设置,回调 URL 可能会默认为 localhost,导致生产环境中的 Google OAuth 失败。
使用方法
使用 Google 登录
要使用 Google 登录,可以使用客户端提供的 signIn.social 函数。signIn 函数接收一个包含以下属性的对象:
provider:要使用的提供者,应设置为google。
import { createAuthClient } from "better-auth/client";
const authClient = createAuthClient();
const signIn = async () => {
const data = await authClient.signIn.social({
provider: "google",
});
};使用 ID Token 登录 Google
要使用 Google 的 ID Token 登录,可以通过 signIn.social 函数传递 ID Token。
当你已经在客户端拥有 Google 的 ID Token,并希望在服务器端使用它登录时,这非常有用。
如果提供了 ID Token,则不会发生重定向,用户将直接登录。
const data = await authClient.signIn.social({
provider: "google",
idToken: {
token: // Google ID Token,
accessToken: // Google 访问令牌
}
})如果你想使用 Google 的一键登录,可以参考 一键登录插件 指南。
跨平台登录(Web、iOS、Android)
Google 会在同一个 Google Cloud 项目中为每个平台分别发放一个 Client ID。将数组传递给 clientId,即可接受来自任一平台的 ID Token。有关共享提供者选项语义,请参阅 clientId。
socialProviders: {
google: {
clientId: [
process.env.GOOGLE_WEB_CLIENT_ID as string,
process.env.GOOGLE_IOS_CLIENT_ID as string,
process.env.GOOGLE_ANDROID_CLIENT_ID as string,
],
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
},
}你的移动应用使用原生 Google SDK 登录,并转发 ID Token:
const { idToken, accessToken } = await GoogleSignin.signIn();
await authClient.signIn.social({
provider: "google",
idToken: { token: idToken, accessToken },
});数组仅会扩展 ID Token 的受众验证。授权码流程仍然使用第一个条目,并与单个 clientSecret 和 redirectURI 配对,因此在同一个提供者块内,这些值不能按平台分别变化。
将登录限制为 Google Workspace
在 Google 提供者上设置 hd,以要求经过验证的 Google Workspace 主机域名声明。Google 也会将此值作为账户选择提示传递,但 Better Auth 会在 Google 签署响应后强制检查返回的 ID token/资料声明。
socialProviders: {
google: {
clientId: process.env.GOOGLE_CLIENT_ID as string,
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
hd: "company.com",
},
}将 hd: "*" 设置为允许任意 Google Workspace 主机域名。只要配置了 hd,没有 hd 声明的令牌都会被拒绝。
自定义的 getUserInfo 回调会替换 Google 内置的回调路径 hd
检查。请从受信任的提供者响应中验证该声明,并在声明缺失或不匹配时返回 null。
直接使用 ID token 登录会遵循提供者的 ID token 验证路径,而 Google One Tap
会单独强制执行已配置的 hd。
始终要求选择账户
如果你希望始终要求用户选择账户,可以在提供者中传递 prompt 参数,并将其设置为 select_account。
socialProviders: {
google: {
prompt: "select_account",
clientId: process.env.GOOGLE_CLIENT_ID as string,
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
},
}请求额外的 Google 权限
如果你的应用需要在用户注册后访问额外的 Google 权限(例如 Google Drive、Gmail 或其他 Google 服务),你可以使用相同的 Google 提供者,通过 linkSocial 方法请求这些权限。
const requestGoogleDriveAccess = async () => {
await authClient.linkSocial({
provider: "google",
scopes: ["https://www.googleapis.com/auth/drive.file"],
});
};
// React 组件中的示例用法
return (
<button onClick={requestGoogleDriveAccess}>
添加 Google Drive 权限
</button>
);这将触发新的 OAuth 流程,请求额外权限。完成后,你的账户将在数据库中获得新的权限,访问令牌将允许你访问请求的 Google API。
确保你使用的是 Better Auth 版本 1.2.7 或更高版本,以避免在请求同一提供者额外权限时出现“社交账户已绑定”错误。
禁用增量授权
默认情况下,Better Auth 会向 Google 的授权端点发送 include_granted_scopes=true,因此新签发的访问令牌除了涵盖当前流程请求的作用域外,还会涵盖之前授权中的作用域。如果每个 OAuth 流程都应该只请求其自身的作用域,请设置 includeGrantedScopes: false。
socialProviders: {
google: {
clientId: process.env.GOOGLE_CLIENT_ID as string,
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
includeGrantedScopes: false,
},
}调用时的 additionalParams.include_granted_scopes 仍然遵循通用的 OAuth 参数优先级规则,并且可以针对单个流程覆盖此提供者默认值。
有关底层参数行为,请参阅 Google 的增量授权文档。
始终获取刷新令牌
Google 仅在用户首次同意授权你的应用时发放刷新令牌。 如果用户已经授权过,后续 OAuth 流程只会返回访问令牌,不会返回刷新令牌。
要始终获取刷新令牌,你可以在提供者选项中设置 accessType 为 offline,并将 prompt 设置为 select_account consent。
socialProviders: {
google: {
clientId: process.env.GOOGLE_CLIENT_ID as string,
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
accessType: "offline",
prompt: "select_account consent",
},
}撤销访问权限: 如果你想为已经授权你的应用的用户获取新的刷新令牌,用户必须先在其 Google 账户设置中撤销你的应用访问权限,然后重新授权。
限制为 Google Workspace 域名
要将登录限制为特定 Google Workspace 域名中的账户,请在调用时传递
hd 参数。这与 Google 的 hd 授权 URL 参数相对应,并且会针对每个请求解析:
await authClient.signIn.social({
provider: "google",
additionalParams: { hd: "example.com" },
});如果该限制对你的应用是静态的,也可以在提供者配置级别设置 hd。