Better Auth 集成
复制包含安装步骤和该插件完整 Markdown 指南的配置 prompt。
概览
“概览”章节Better Auth 可与以下方案良好配合 @capgo/capacitor-social-login 当你希望在设备上使用原生登录,但仍希望由 Better Auth 在后端创建和管理会话时。
本页重点介绍两种最合适的集成模式:
- Google、Apple 和 Facebook 的原生 token 交接
- 适用于 Auth0、Okta、Keycloak 和自定义 OIDC 服务器等提供商的 Better Auth Generic OAuth
该用哪种模式
章节标题:“使用哪种模式”使用原生 token 传递
标题为“使用原生 token 交接”的章节使用 SocialLogin.login() 首先,然后将返回的 token 通过以下命令发送给 Better Auth: authClient.signIn.social() 当你使用以下服务时:
- Apple
使用 Better Auth 通用 OAuth
标题为“使用 Better Auth 通用 OAuth”的章节当你使用以下服务时,让 Better Auth 接管完整的 OAuth 重定向流程:
- Auth0
- Okta
- Keycloak
- GitHub
- OneLogin
- 任意自定义 OAuth2 或 OIDC 提供商
这样可以将会话交换保留在 Better Auth 一侧,避免在两个系统之间重复重定向逻辑。
Better Auth 服务器配置
标题为“Better Auth 服务器配置”的章节首先,配置 Better Auth 以支持您想要使用的社交提供商:
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, }, apple: { clientId: process.env.APPLE_CLIENT_ID as string, clientSecret: process.env.APPLE_CLIENT_SECRET as string, appBundleIdentifier: process.env.APPLE_APP_BUNDLE_IDENTIFIER as string, }, facebook: { clientId: process.env.FACEBOOK_CLIENT_ID as string, clientSecret: process.env.FACEBOOK_CLIENT_SECRET as string, }, }, trustedOrigins: ['https://appleid.apple.com'],});Better Auth 客户端配置
标题为“Better Auth 客户端配置”的章节import { createAuthClient } from 'better-auth/client';
export const authClient = createAuthClient({ baseURL: 'https://auth.example.com',});如果你使用 React,请使用应用已经在用的 Better Auth React 客户端包。Token 传递模式保持不变。
Google 示例
标题为“Google 示例”的章节这是原生移动端 Google 登录最简洁的集成方式:
import { SocialLogin } from '@capgo/capacitor-social-login';import { authClient } from '@/lib/auth-client';
const googleResult = await SocialLogin.login({ provider: 'google', options: { scopes: ['profile', 'email'], },});
if (googleResult.result.responseType !== 'online' || !googleResult.result.idToken) { throw new Error('Google online mode with idToken is required for Better Auth.');}
await authClient.signIn.social({ provider: 'google', idToken: { token: googleResult.result.idToken, accessToken: googleResult.result.accessToken?.token, }, callbackURL: '/dashboard',});Apple 示例
标题为“Apple 示例”的章节对于 Apple,请将同一个 nonce 传给原生登录请求和 Better Auth:
import { SocialLogin } from '@capgo/capacitor-social-login';import { authClient } from '@/lib/auth-client';
const nonce = crypto.randomUUID();
const appleResult = await SocialLogin.login({ provider: 'apple', options: { scopes: ['email', 'name'], nonce, },});
if (!appleResult.result.idToken) { throw new Error('Apple idToken is required for Better Auth.');}
await authClient.signIn.social({ provider: 'apple', idToken: { token: appleResult.result.idToken, nonce, accessToken: appleResult.result.accessToken?.token, }, callbackURL: '/dashboard',});Facebook 示例
章节标题:“Facebook 示例”Better Auth 文档介绍了两种 Facebook 交接模式:
- iOS Limited Login:传递
idToken - Access-token 流程:将 access token 同时作为
token以及accessToken
这适用于来自以下来源的响应结构: @capgo/capacitor-social-login:
import { SocialLogin } from '@capgo/capacitor-social-login';import { authClient } from '@/lib/auth-client';
const facebookResult = await SocialLogin.login({ provider: 'facebook', options: { permissions: ['email', 'public_profile'], },});
const betterAuthToken = facebookResult.result.idToken ? { token: facebookResult.result.idToken, } : facebookResult.result.accessToken?.token ? { token: facebookResult.result.accessToken.token, accessToken: facebookResult.result.accessToken.token, } : null;
if (!betterAuthToken) { throw new Error('Facebook idToken or access token is required for Better Auth.');}
await authClient.signIn.social({ provider: 'facebook', idToken: betterAuthToken, callbackURL: '/dashboard',});使用 Better Auth 的通用 OAuth 提供商
章节标题:“使用 Better Auth 的通用 OAuth 提供商”对于 Auth0、Okta、Keycloak、GitHub、Microsoft Entra ID 及类似提供商,Better Auth 的 Generic OAuth 插件通常比从以下来源传递 token 更合适: SocialLogin.login({ provider: 'oauth2' }).
Better Auth 服务端
标题为“Better Auth 服务端”的章节import { betterAuth } from 'better-auth';import { genericOAuth } from 'better-auth/plugins';
export const auth = betterAuth({ plugins: [ genericOAuth({ config: [ { providerId: 'keycloak', discoveryUrl: 'https://sso.example.com/realms/mobile/.well-known/openid-configuration', clientId: process.env.KEYCLOAK_CLIENT_ID as string, clientSecret: process.env.KEYCLOAK_CLIENT_SECRET as string, }, ], }), ],});Better Auth 客户端
标题为“Better Auth 客户端”的章节import { createAuthClient } from 'better-auth/client';import { genericOAuthClient } from 'better-auth/client/plugins';
export const authClient = createAuthClient({ baseURL: 'https://auth.example.com', plugins: [genericOAuthClient()],});
await authClient.signIn.oauth2({ providerId: 'keycloak', callbackURL: '/dashboard',});Better Auth Generic OAuth 的 Provider 示例
标题为“Better Auth Generic OAuth 的 Provider 示例”的章节Better Auth 为多个 Provider 内置了预配置的 helper。它们与 social-login 插件文档中看到的额外 Provider 示例最为接近。
Auth0
标题为“Auth0”的章节import { betterAuth } from 'better-auth';import { auth0, genericOAuth } from 'better-auth/plugins';
export const auth = betterAuth({ plugins: [ genericOAuth({ config: [ auth0({ providerId: 'auth0', domain: 'dev-example.eu.auth0.com', clientId: process.env.AUTH0_CLIENT_ID as string, clientSecret: process.env.AUTH0_CLIENT_SECRET as string, scopes: ['openid', 'profile', 'email', 'offline_access'], }), ], }), ],});await authClient.signIn.oauth2({ providerId: 'auth0', callbackURL: '/dashboard',});Microsoft Entra ID
标题为“Microsoft Entra ID”的章节import { betterAuth } from 'better-auth';import { genericOAuth, microsoftEntraId } from 'better-auth/plugins';
export const auth = betterAuth({ plugins: [ genericOAuth({ config: [ microsoftEntraId({ providerId: 'entra', tenantId: 'common', clientId: process.env.AZURE_CLIENT_ID as string, clientSecret: process.env.AZURE_CLIENT_SECRET as string, scopes: ['openid', 'profile', 'email', 'User.Read'], }), ], }), ],});await authClient.signIn.oauth2({ providerId: 'entra', callbackURL: '/dashboard',});Okta
标题为“Okta”的章节import { betterAuth } from 'better-auth';import { genericOAuth, okta } from 'better-auth/plugins';
export const auth = betterAuth({ plugins: [ genericOAuth({ config: [ okta({ providerId: 'okta', issuer: 'https://dev-12345.okta.com/oauth2/default', clientId: process.env.OKTA_CLIENT_ID as string, clientSecret: process.env.OKTA_CLIENT_SECRET as string, scopes: ['openid', 'profile', 'email', 'offline_access'], }), ], }), ],});await authClient.signIn.oauth2({ providerId: 'okta', callbackURL: '/dashboard',});Keycloak
标题为“Keycloak”的章节import { betterAuth } from 'better-auth';import { genericOAuth, keycloak } from 'better-auth/plugins';
export const auth = betterAuth({ plugins: [ genericOAuth({ config: [ keycloak({ providerId: 'keycloak', issuer: 'https://sso.example.com/realms/mobile', clientId: process.env.KEYCLOAK_CLIENT_ID as string, clientSecret: process.env.KEYCLOAK_CLIENT_SECRET as string, scopes: ['openid', 'profile', 'email', 'offline_access'], }), ], }), ],});await authClient.signIn.oauth2({ providerId: 'keycloak', callbackURL: '/dashboard',});GitHub 搭配手动 Generic OAuth 配置
标题为“GitHub 手动通用 OAuth 配置”的章节GitHub 在通用 OAuth 页面没有 Better Auth 辅助功能,因此请使用手动配置:
import { betterAuth } from 'better-auth';import { genericOAuth } from 'better-auth/plugins';
export const auth = betterAuth({ plugins: [ genericOAuth({ config: [ { providerId: 'github', clientId: process.env.GITHUB_CLIENT_ID as string, clientSecret: process.env.GITHUB_CLIENT_SECRET as string, authorizationUrl: 'https://github.com/login/oauth/authorize', tokenUrl: 'https://github.com/login/oauth/access_token', userInfoUrl: 'https://api.github.com/user', scopes: ['read:user', 'user:email'], pkce: true, }, ], }), ],});await authClient.signIn.oauth2({ providerId: 'github', callbackURL: '/dashboard',});注意事项
标题为“注意事项”的章节-
使用 Google 在线模式 Better Auth 需要
idToken,因此google.mode: 'offline'不适合此交接流程。 -
复用 Apple nonce 只需生成一次,先传给 Apple 原生登录,再把同一个值传给 Better Auth。
-
按平台分别处理 Facebook iOS 上的 Limited Login 会返回 ID token,其他流程可能只返回 access token。
-
除非有理由,否则不要混用 Generic OAuth 流程 如果 Better Auth 负责 OAuth 提供商配置,就让 Better Auth 也负责重定向流程。
延伸阅读
标题为“延伸阅读”的章节- Better Auth Google 提供商文档
- Better Auth Apple 提供商文档
- Better Auth Facebook 提供商文档
- Better Auth Generic OAuth 插件文档
- Social Login OAuth2 和 OIDC 提供商
从 Better Auth 集成继续
章节标题“继续 Better Auth 集成”如果你正在使用 Better Auth 集成 用来规划身份验证和账户流程,并将它与 使用 @capgo/capacitor-social-login 关于使用 @capgo/capacitor-social-login 的原生能力, @capgo/capacitor-social-login 在 @capgo/capacitor-social-login 中查看实现细节, @capgo/capacitor-passkey 有关 @capgo/capacitor-passkey 的实现细节, @capgo/capacitor-native-biometric 以及 @capgo/capacitor-native-biometric 中的实现细节, 双因素认证 有关双重身份验证的实现细节。