上次登录方式
最后登录方式插件会跟踪用户最近使用的认证方法(电子邮件、OAuth 提供商等)。这使你能够在登录页面上显示有用的提示,例如“上次使用 Google 登录”,或根据用户偏好优先显示某些登录方式。
🌐 The last login method plugin tracks the most recent authentication method used by users (email, OAuth providers, etc.). This enables you to display helpful indicators on login pages, such as "Last signed in with Google" or prioritize certain login methods based on user preferences.
安装
🌐 Installation
将插件添加到你的认证配置
import { betterAuth } from "better-auth"
import { lastLoginMethod } from "better-auth/plugins"
export const auth = betterAuth({
// ... other config options
plugins: [
lastLoginMethod()
]
})Add the client plugin to your auth client
import { createAuthClient } from "better-auth/client"
import { lastLoginMethodClient } from "better-auth/client/plugins"
export const authClient = createAuthClient({
plugins: [
lastLoginMethodClient()
]
})用法
🌐 Usage
安装后,该插件会自动跟踪用户最后使用的身份验证方式。然后,你可以在应用中检索并显示此信息。
🌐 Once installed, the plugin automatically tracks the last authentication method used by users. You can then retrieve and display this information in your application.
获取最后使用的方法
🌐 Getting the Last Used Method
客户端插件提供了几种方法来处理上次登录方式:
🌐 The client plugin provides several methods to work with the last login method:
import { authClient } from "@/lib/auth-client"
// Get the last used login method
const lastMethod = authClient.getLastUsedLoginMethod()
console.log(lastMethod) // "google", "email", "github", etc.
// Check if a specific method was last used
const wasGoogle = authClient.isLastUsedLoginMethod("google")
// Clear the stored method
authClient.clearLastUsedLoginMethod()用户界面集成示例
🌐 UI Integration Example
以下是使用该插件增强登录页面的方法:
🌐 Here's how to use the plugin to enhance your login page:
import { authClient } from "@/lib/auth-client"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
export function SignInPage() {
const lastMethod = authClient.getLastUsedLoginMethod()
return (
<div className="space-y-4">
<h1>Sign In</h1>
<div className="relative">
<Button
onClick={() => authClient.signIn.email({...})}
variant={lastMethod === "email" ? "default" : "outline"}
className="w-full"
>
Sign in with Email
{lastMethod === "email" && (
<Badge className="ml-2">Last used</Badge>
)}
</Button>
</div>
<div className="relative">
<Button
onClick={() => authClient.signIn.social({ provider: "google" })}
variant={lastMethod === "google" ? "default" : "outline"}
className="w-full"
>
Continue with Google
{lastMethod === "google" && (
<Badge className="ml-2">Last used</Badge>
)}
</Button>
</div>
<div className="relative">
<Button
onClick={() => authClient.signIn.social({ provider: "github" })}
variant={lastMethod === "github" ? "default" : "outline"}
className="w-full"
>
Continue with GitHub
{lastMethod === "github" && (
<Badge className="ml-2">Last used</Badge>
)}
</Button>
</div>
</div>
)
}数据库持久化
🌐 Database Persistence
默认情况下,最后的登录方式仅保存在 cookies 中。若需更持久的追踪和分析,你可以启用数据库存储。
🌐 By default, the last login method is stored only in cookies. For more persistent tracking and analytics, you can enable database storage.
启用数据库存储
在插件配置中将 storeInDatabase 设置为 true:
import { betterAuth } from "better-auth"
import { lastLoginMethod } from "better-auth/plugins"
export const auth = betterAuth({
plugins: [
lastLoginMethod({
storeInDatabase: true
})
]
})Run database migration
该插件会自动向你的用户表添加一个 lastLoginMethod 字段。运行迁移以应用更改:
npx @better-auth/cli migratenpx @better-auth/cli generateAccess database field
当启用数据库存储时,lastLoginMethod 字段将在用户对象中可用:
import { auth } from "@/lib/auth"
// Server-side access
const session = await auth.api.getSession({ headers })
console.log(session?.user.lastLoginMethod) // "google", "email", etc.
// Client-side access via session
const { data: session } = authClient.useSession()
console.log(session?.user.lastLoginMethod)数据库架构
🌐 Database Schema
当启用 storeInDatabase 时,插件会向 user 表中添加以下字段:
🌐 When storeInDatabase is enabled, the plugin adds the following field to the user table:
表:user
🌐 Table: user
| Field Name | Type | Key | Description |
|---|---|---|---|
| lastLoginMethod | string | The last authentication method used by the user |
自定义模式配置
🌐 Custom Schema Configuration
你可以自定义数据库字段名称:
🌐 You can customize the database field name:
import { betterAuth } from "better-auth"
import { lastLoginMethod } from "better-auth/plugins"
export const auth = betterAuth({
plugins: [
lastLoginMethod({
storeInDatabase: true,
schema: {
user: {
lastLoginMethod: "last_auth_method" // Custom field name
}
}
})
]
})配置选项
🌐 Configuration Options
最后一次登录方式插件接受以下选项:
🌐 The last login method plugin accepts the following options:
服务器选项
🌐 Server Options
import { betterAuth } from "better-auth"
import { lastLoginMethod } from "better-auth/plugins"
export const auth = betterAuth({
plugins: [
lastLoginMethod({
// Cookie configuration
cookieName: "better-auth.last_used_login_method", // Default: "better-auth.last_used_login_method"
maxAge: 60 * 60 * 24 * 30, // Default: 30 days in seconds
// Database persistence
storeInDatabase: false, // Default: false
// Custom method resolution
customResolveMethod: (ctx) => {
// Custom logic to determine the login method
if (ctx.path === "/oauth/callback/custom-provider") {
return "custom-provider"
}
// Return null to use default resolution
return null
},
// Schema customization (when storeInDatabase is true)
schema: {
user: {
lastLoginMethod: "custom_field_name"
}
}
})
]
})cookieName: string
- 用于存储上次登录方式的 Cookie 名称
- 默认:
"better-auth.last_used_login_method" - 注意:此 cookie 为
httpOnly: false,以允许客户端 JavaScript 访问 UI 功能
最大年龄: number
- Cookie 过期时间(秒)
- 默认:
2592000(30天)
storeInDatabase: boolean
- 是否在数据库中存储上次的登录方式
- 默认:
false - 启用后,会在用户表中添加一个
lastLoginMethod字段
customResolveMethod: (ctx: GenericEndpointContext) => string | null
- 自定义函数用于从请求上下文确定登录方式
- 返回
null以使用默认的解析逻辑 - 适用于自定义 OAuth 提供商或身份验证流程
模式: object
- 在启用
storeInDatabase时自定义数据库字段名称 - 允许将
lastLoginMethod字段映射到自定义列名
客户选项
🌐 Client Options
import { createAuthClient } from "better-auth/client"
import { lastLoginMethodClient } from "better-auth/client/plugins"
export const authClient = createAuthClient({
plugins: [
lastLoginMethodClient({
cookieName: "better-auth.last_used_login_method" // Default: "better-auth.last_used_login_method"
})
]
})cookieName: string
- 用于读取上次登录方式的 cookie 名称
- 必须与服务器端
cookieName配置匹配 - 默认:
"better-auth.last_used_login_method"
默认方法解析
🌐 Default Method Resolution
默认情况下,该插件会跟踪以下身份验证方法:
🌐 By default, the plugin tracks these authentication methods:
- 电子邮件验证:
"email" - OAuth 提供商:提供商 ID(例如,
"google"、"github"、"discord") - OAuth2 回调:来自 URL 路径的提供者 ID
- 注册方式:与登录方式的跟踪相同
该插件会自动从这些端点检测方法:
🌐 The plugin automatically detects the method from these endpoints:
/callback/:id- 带有提供者 ID 的 OAuth 回调/oauth2/callback/:id- 带有提供商 ID 的 OAuth2 回调/sign-in/email- 电子邮件登录/sign-up/email- 邮箱注册
跨字段支持
🌐 Cross-Domain Support
该插件会自动继承来自 Better Auth 集中式 Cookie 系统的 Cookie 设置。这解决了上次登录方式无法在以下情况中保持的问题:
🌐 The plugin automatically inherits cookie settings from Better Auth's centralized cookie system. This solves the problem where the last login method wouldn't persist across:
- 跨子域设置:
auth.example.com→app.example.com - 跨域设置:
api.company.com→app.different.com
当你在 Better Auth 配置中启用 crossSubDomainCookies 或 crossOriginCookies 时,插件将自动使用与会话 Cookie 相同的域、Secure 和 SameSite 设置,确保在应用中行为一致。
🌐 When you enable crossSubDomainCookies or crossOriginCookies in your Better Auth config, the plugin will automatically use the same domain, secure, and sameSite settings as your session cookies, ensuring consistent behavior across your application.
高级示例
🌐 Advanced Examples
自定义提供者跟踪
🌐 Custom Provider Tracking
如果你有自定义的 OAuth 提供商或身份验证方法,你可以使用 customResolveMethod 选项:
🌐 If you have custom OAuth providers or authentication methods, you can use the customResolveMethod option:
import { betterAuth } from "better-auth"
import { lastLoginMethod } from "better-auth/plugins"
export const auth = betterAuth({
plugins: [
lastLoginMethod({
customResolveMethod: (ctx) => {
// Track custom SAML provider
if (ctx.path === "/saml/callback") {
return "saml"
}
// Track magic link authentication
if (ctx.path === "/magic-link/verify") {
return "magic-link"
}
// Track phone authentication
if (ctx.path === "/sign-in/phone") {
return "phone"
}
// Return null to use default logic
return null
}
})
]
})在 Expo 中的使用
🌐 Usage with Expo
在使用 Expo 的 Better Auth 时,请确保从 @better-auth/expo/plugins 导入客户端插件,而不是从 better-auth/plugins/client 导入。这可以确保上次登录方式能够使用配置的存储正确保存。
🌐 When using Better Auth with Expo, make sure to import the client plugin from @better-auth/expo/plugins rather than from better-auth/plugins/client. This ensures the last login method is stored correctly using the configured storage.
import { createAuthClient } from "better-auth/react"
import { expoClient } from "@better-auth/expo"
import { lastLoginMethodClient } from "@better-auth/expo/plugins"
import * as SecureStore from "expo-secure-store"
export const authClient = createAuthClient({
plugins: [
expoClient({
scheme: "myapp",
storagePrefix: "myapp",
storage: SecureStore,
}),
lastLoginMethodClient({
storagePrefix: "myapp",
storage: SecureStorage,
})
]
})在仅使用 Expo 的应用中,如果不需要浏览器支持,可以省略服务器插件,只依赖客户端插件。