通用 OAuth
通用 OAuth 插件提供了一种灵活的方式,用于与任何 OAuth 提供者集成身份验证。它支持 OAuth 2.0 和 OpenID Connect (OIDC) 流程,使您能够轻松地为应用程序添加社交登录或自定义 OAuth 认证。
安装
将插件添加到认证配置中
要使用通用 OAuth 插件,请将其添加到您的认证配置中。
import { betterAuth } from "better-auth"
import { genericOAuth } from "better-auth/plugins"
export const auth = betterAuth({
// ... 其他配置选项
plugins: [
genericOAuth({
config: [
{
providerId: "provider-id",
clientId: "test-client-id",
clientSecret: "test-client-secret",
discoveryUrl: "https://auth.example.com/.well-known/openid-configuration",
// ... 其他配置选项
},
// 根据需要添加更多提供者
]
})
]
})
添加客户端插件
在您的认证客户端实例中包含通用 OAuth 客户端插件。
import { createAuthClient } from "better-auth/client"
import { genericOAuthClient } from "better-auth/client/plugins"
export const authClient = createAuthClient({
plugins: [
genericOAuthClient()
]
})
使用方法
通用 OAuth 插件提供了用于启动 OAuth 流程和处理回调的端点。以下是它们的使用方法:
启动 OAuth 登录
要开始 OAuth 登录流程:
const { data, error } = await authClient.signIn.oauth2({ providerId: "provider-id", // required callbackURL: "/dashboard", errorCallbackURL: "/error-page", newUserCallbackURL: "/welcome", disableRedirect: false, scopes: ["my-scope"], requestSignUp: false,});
属性 | 描述 | 类型 |
---|---|---|
providerId | OAuth 提供商的 ID。 | string |
callbackURL? | 登录后重定向的 URL。 | string |
errorCallbackURL? | 发生错误时重定向的 URL。 | string |
newUserCallbackURL? | 新用户登录后重定向的 URL。 | string |
disableRedirect? | 禁用重定向。 | boolean |
scopes? | 传递给提供商授权请求的作用域。 | string[] |
requestSignUp? | 显式请求注册。当此提供商的 disableImplicitSignUp 为 true 时很有用。 | boolean |
关联 OAuth 账户
要将 OAuth 账户关联到现有用户:
const { data, error } = await authClient.oauth2.link({ providerId: "my-provider-id", // required callbackURL: "/successful-link", // required});
属性 | 描述 | 类型 |
---|---|---|
providerId | OAuth 提供商 ID。 | string |
callbackURL | 账户关联完成后重定向的 URL。 | string |
处理 OAuth 回调
插件挂载了一个路由来处理 OAuth 回调 /oauth2/callback/:providerId
。这意味着默认情况下将使用 ${baseURL}/api/auth/oauth2/callback/:providerId
作为回调 URL。请确保您的 OAuth 提供商已配置为使用此 URL。
配置
当将插件添加到您的身份验证配置时,您可以配置多个 OAuth 提供程序。每个提供程序配置对象支持以下选项:
interface GenericOAuthConfig {
providerId: string;
discoveryUrl?: string;
authorizationUrl?: string;
tokenUrl?: string;
userInfoUrl?: string;
clientId: string;
clientSecret: string;
scopes?: string[];
redirectURI?: string;
responseType?: string;
prompt?: string;
pkce?: boolean;
accessType?: string;
getUserInfo?: (tokens: OAuth2Tokens) => Promise<User | null>;
}
其他提供程序配置
providerId: 用于标识 OAuth 提供程序配置的唯一字符串。
discoveryUrl: (可选)用于获取提供程序的 OAuth 2.0/OIDC 配置的 URL。如果提供,可以自动发现如 authorizationUrl
、tokenUrl
和 userInfoUrl
等端点。
authorizationUrl: (可选)OAuth 提供程序的授权端点。如果使用 discoveryUrl
则不需要。
tokenUrl: (可选)OAuth 提供程序的令牌端点。如果使用 discoveryUrl
则不需要。
userInfoUrl: (可选)用于获取用户配置文件信息的端点。如果使用 discoveryUrl
则不需要。
clientId: 由您的提供程序颁发的 OAuth 客户端 ID。
clientSecret: 由您的提供程序颁发的 OAuth 客户端密钥。
scopes: (可选)向提供程序请求的权限范围数组(例如 ["openid", "email", "profile"]
)。
redirectURI: (可选)用于 OAuth 流程的重定向 URI。如果未设置,将根据您应用的基础 URL 构造默认值。
responseType: (可选)OAuth 响应类型。对于授权码流程,默认为 "code"
。
responseMode: (可选)授权码请求的响应模式,例如 "query"
或 "form_post"
。
prompt: (可选)控制身份验证体验(例如强制登录、同意等)。
pkce:(可选)如果设为 true,将启用 PKCE(Proof Key for Code Exchange,代码交换证明密钥)以增强安全性。默认值为 false
。
accessType:(可选)授权请求的访问类型。使用 "offline"
可请求刷新令牌。
getUserInfo:(可选)一个自定义函数,用于根据 OAuth 令牌从提供商获取用户信息。如未提供,将使用默认的 fetch 方法。
mapProfileToUser:(可选)一个函数,用于将提供商的用户资料映射到您应用的用户对象。适用于自定义字段映射或转换。
authorizationUrlParams:(可选)要添加到授权 URL 的额外查询参数。这些参数可以覆盖默认参数。
disableImplicitSignUp:(可选)如果设为 true,将禁用新用户的自动注册。必须通过注册意图显式请求登录。
disableSignUp:(可选)如果设为 true,将完全禁用新用户的注册。仅现有用户可以登录。
authentication:(可选)令牌请求的身份验证方法。可选值为 'basic'
或 'post'
。默认值为 'post'
。
discoveryHeaders:(可选)在发现请求中包含的自定义请求头。适用于需要特殊请求头的提供商。
authorizationHeaders:(可选)在授权请求中包含的自定义请求头。适用于需要特殊请求头的提供商。
overrideUserInfo:(可选)如果设为 true,每次用户登录时,数据库中的用户信息将被提供商的信息覆盖。默认值为 false
。
高级用法
自定义用户信息获取
您可以提供自定义的 getUserInfo
函数来处理特定提供商的特殊需求:
genericOAuth({
config: [
{
providerId: "custom-provider",
// ... 其他配置选项
getUserInfo: async (tokens) => {
// 自定义获取并返回用户信息的逻辑
const userInfo = await fetchUserInfoFromCustomProvider(tokens);
return {
id: userInfo.sub,
email: userInfo.email,
name: userInfo.name,
// ... 根据需要映射其他字段
};
}
}
]
})
映射用户信息字段
如果提供商返回的用户信息格式与预期不符,或者您需要映射其他字段,可以使用 mapProfileToUser
方法:
genericOAuth({
config: [
{
providerId: "custom-provider",
// ... 其他配置选项
mapProfileToUser: async (profile) => {
return {
firstName: profile.given_name,
// ... 根据需要映射其他字段
};
}
}
]
})
错误处理
该插件内置了对常见 OAuth 问题的错误处理功能。错误通常会被重定向到您应用程序的错误页面,并在 URL 参数中包含相应的错误信息。如果未提供回调 URL,用户将被重定向到 Better Auth 的默认错误页面。