一键登录
用于 Better Auth 的一键登录插件
一键登录插件允许用户通过 Google 的 One Tap API 只需轻点一次即可登录。该插件为您提供一个简单的方式将 One Tap 集成到您的应用中,负责处理客户端和服务器端的逻辑。
安装
添加服务器端插件
将 One Tap 插件添加到您的认证配置中:
import { betterAuth } from "better-auth";
import { oneTap } from "better-auth/plugins";
export const auth = betterAuth({
plugins: [
oneTap(), // 添加 One Tap 服务器端插件
]
});添加客户端插件
添加客户端插件并指定用户登录后应重定向到的位置,以及是否需要额外验证(如双因素认证)。
import { createAuthClient } from "better-auth/client";
import { oneTapClient } from "better-auth/client/plugins";
export const authClient = createAuthClient({
plugins: [
oneTapClient({
clientId: "YOUR_CLIENT_ID",
// 可选的客户端配置:
autoSelect: false,
cancelOnTapOutside: true,
context: "signin",
additionalOptions: {
// Google 初始化方法的任何额外选项
},
// 配置提示行为和指数退避:
promptOptions: {
baseDelay: 1000, // 重试延迟基数(毫秒,默认:1000)
maxAttempts: 5 // 触发 onPromptNotification 前的最大尝试次数(默认:5)
}
})
]
});用法
提示模式(默认)
要显示 One Tap 弹窗,只需在您的认证客户端调用 oneTap 方法:
import { authClient } from "@/lib/auth-client";
await authClient.oneTap(); 按钮模式
如果想展示“使用 Google 登录”按钮而不是自动弹出提示,可使用 button 选项:
// 在您的组件内
<div id="google-signin-button"></div>
// 使用按钮配置调用 oneTap
await authClient.oneTap({
button: {
container: "#google-signin-button", // CSS 选择器或 HTMLElement
config: {
theme: "outline",
size: "large",
type: "standard",
text: "signin_with"
}
}
});import { useEffect, useRef } from "react";
function SignInButton() {
const buttonRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (buttonRef.current) {
authClient.oneTap({
button: {
container: buttonRef.current,
config: {
theme: "filled_blue",
size: "large"
}
}
});
}
}, []);
return <div ref={buttonRef}></div>;
}自定义重定向行为
默认情况下,登录成功后插件会硬跳转到 /。您可以按以下方法自定义该行为:
避免硬跳转
传递带有 onSuccess 回调的 fetchOptions,用于在不重新加载页面的情况下处理登录响应:
import { authClient } from "@/lib/auth-client";
await authClient.oneTap({
fetchOptions: {
onSuccess: () => {
// 例如,使用路由器导航而不完整重载页面:
router.push("/dashboard");
}
}
});指定自定义回调 URL
如果登录后想进行硬跳转至不同页面,使用 callbackURL 选项:
import { authClient } from "@/lib/auth-client";
await authClient.oneTap({
callbackURL: "/dashboard"
});使用指数退避处理提示被关闭
若用户关闭或跳过提示,插件将根据您配置的 promptOptions 使用指数退避重试显示 One Tap 提示。
如果达到最大尝试次数仍未成功登录,您可以使用 onPromptNotification 回调得到通知,允许您渲染替代的用户界面(例如传统的 Google 登录按钮),以便用户手动重新开始流程:
import { authClient } from "@/lib/auth-client";
await authClient.oneTap({
onPromptNotification: (notification) => {
console.warn("提示已被关闭或跳过。请考虑显示替代的登录选项。", notification);
// 在这里渲染您的替代 UI
}
});客户端选项
clientId: 您的 Google One Tap API 的客户端 ID。autoSelect: 如果用户已登录,自动选择账户。默认为 false。cancelOnTapOutside: 当用户点击弹窗外部时取消 One Tap 弹窗。请注意,当 FedCM 处于活动状态时,此选项可能无效,因为浏览器会管理取消行为。默认为 true。uxMode: Google One Tap 流程使用的模式。可以是 "popup" 或 "redirect"。默认为 "popup"。context: 应使用 One Tap API 的上下文。可以是 "signin"、"signup" 或 "use"。默认为 "signin"。additionalOptions: 额外的选项,按照 Google Identity Services 文档 传递给 Google 的初始化方法。promptOptions: 提示行为和指数退避的配置:baseDelay: 重试延迟基数(毫秒)。默认是 1000。maxAttempts: 触发 onPromptNotification 回调前的最大尝试次数。默认是 5。fedCM: 启用时,调用navigator.credentials.preventSilentAccess()以在登出时清除浏览器的 FedCM 凭据状态。FedCM 本身由 Google Identity Services 库管理,无法禁用。默认是 true。
按钮模式选项
使用按钮模式时,向 oneTap 方法传递 button 对象,包含以下属性:
container: 渲染按钮的 HTML 元素或 CSS 选择器(必需)config: 按钮配置选项(可选):type: 按钮类型 -"standard"(默认)或"icon"(仅图标)theme: 按钮主题 -"outline"(默认)、"filled_blue"或"filled_black"size: 按钮大小 -"large"(默认)、"medium"或"small"text: 按钮文本 -"signin_with"(默认)、"signup_with"、"continue_with"或"signin"shape: 按钮形状 -"rectangular"(默认)、"pill"、"circle"或"square"logo_alignment: Google Logo 对齐方式 -"left"(默认)或"center"(仅标准按钮)width: 最小按钮宽度(像素,最大 400)locale: 使用指定的语言代码显示按钮(例如"zh_CN")
服务器端选项
disableSignUp: 禁用注册选项,仅允许现有用户登录。默认是 false。clientId: 如果社交提供程序配置中未提供客户端 ID,可以在此处选择性传递客户端 ID。
授权的 JavaScript 来源
请确保为您的客户端 ID 配置已授权的 JavaScript 来源(例如 http://localhost:3000, https://example.com)。这是 Google One Tap API 的必需步骤,除非正确设置了来源,否则无法正常工作。