跳过内容

Better Auth Integration

GitHub

Better Auth 与 @capgo/capacitor-social-login 当您希望在设备上使用原生登录,但仍希望 Better Auth 在您的后端创建和管理会话时,Better Auth 就会发挥作用。

本页面重点介绍两个最合适的集成模式:

  • 原生令牌传递(Google、Apple、Facebook)
  • 更好的认证(通用OAuth)- Auth0、Okta、Keycloak、自定义OIDC服务器等提供商

使用哪种模式

使用哪种模式

使用原生令牌传递

使用

首先,然后将返回的令牌发送到更好的认证中 SocialLogin.login() 当您使用时: authClient.signIn.social() Google

  • Apple
  • Facebook
  • when you use:

使用更好的认证通用 OAuth

标题:使用更好的认证通用 OAuth

当您使用时,让更好的认证完全拥有 OAuth 重定向流:

  • Auth0
  • Okta
  • Keycloak
  • GitHub
  • OneLogin
  • 任何自定义 OAuth2 或 OIDC 提供商

这保持了会话交换在更好的认证侧,并避免了在两个系统之间重复重定向逻辑。

更好的认证服务器设置

标题:更好的认证服务器设置

首先配置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客户端包,您的应用程序已经使用。令牌传递模式保持不变。

这是native移动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',
});

对于苹果,传递相同的nonce给native登录请求和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',
});

Better Auth文档了两个Facebook手动模式:

  • iOS Limited Login:传递 idToken
  • 访问令牌流:传递访问令牌作为 tokenaccessToken

与此响应形状一起工作 @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',
});

通用 OAuth 提供商

标题:通用 OAuth 提供商

对于 Auth0、Okta、Keycloak、GitHub、Microsoft Entra ID 和类似提供商,Better Auth 通用 OAuth 插件通常比从 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 examples for Better Auth Generic OAuth

Better Auth 提供了多个预配置的助手,用于多个提供商。这些助手与社交登录插件文档中看到的额外提供商示例非常相似。

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

复制到剪贴板
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',
});
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使用手动通用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',
});

注意事项和警告

注意和注意事项
  1. 使用Google在线模式 Better Auth需要 idToken,所以 google.mode: 'offline' 不是适合此手续流程的正确选择。

  2. 重用Apple nonce 生成一次,发送给Apple原生登录,然后将相同的值发送给Better Auth。

  3. 根据平台处理Facebook iOS上的有限登录会给你一个ID令牌。其他流程可能只给你一个访问令牌。

  4. 不要混合通用OAuth流程,除非有原因 如果Better Auth拥有OAuth提供商配置,则让Better Auth拥有重定向流程。

进一步阅读

进一步阅读

继续使用Better Auth Integration

继续使用Better Auth集成

如果您正在使用 更好的认证集成 为了规划身份验证和账户流程,连接它 使用@capgo/capacitor社交登录 为使用@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的实现细节, 和 双因素认证 为双因素认证的实现细节。