跳过内容

更好的认证集成

GitHub

Overview

概述

标题为“概述” @capgo/capacitor-social-login Better Auth 与

当您希望在设备上使用原生登录,但仍希望 Better Auth 在后端创建和管理会话时,Better Auth 就会很好地工作。

  • 本页面重点介绍适合的两种集成模式:
  • 更好的身份验证通用OAuth,支持Auth0、Okta、Keycloak等提供商,以及自定义OIDC服务器

选择使用哪种模式

标题:选择使用哪种模式

使用原生令牌传递

标题:使用原生令牌传递

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

  • Google
  • Apple
  • Facebook

使用更好的身份验证通用OAuth

Section titled “使用Better Auth Generic OAuth”

当您使用时,让Better Auth完全控制OAuth重定向流程:

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

在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 登录的最干净的集成路径:

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 到原生登录请求和 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 有限登录:传递 idToken
  • 访问令牌流:传递访问令牌作为 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',
});

通用 OAuth 提供商与 Better Auth

通用 OAuth 提供商与 Better Auth

对于 Auth0、Okta、Keycloak、GitHub、Microsoft Entra ID 和类似提供商,Better Auth 的 Generic OAuth 插件通常比从 Better Auth 服务器传递令牌更合适 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 通用 OAuth 提供商示例

Better Auth 通用 OAuth 提供商示例

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

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 在通用 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 上的 Limited Login 给你一个 ID 令牌。其他流程可能只给你一个访问令牌。

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

从更好的认证集成中继续

标题:从更好的认证集成中继续

如果您正在使用 更好的认证集成 来规划认证和帐户流程,连接它与 使用 @capgo/capacitor-social-login 为在使用 @capgo/capacitor-social-login 中的原生能力 @capgo/capacitor-社交登录 为 @capgo/capacitor-social-login 的实现细节 @capgo/capacitor-passkey 为 @capgo/capacitor-passkey 的实现细节 @capgo/capacitor-native-biometric 为 @capgo/capacitor-native-biometric 的实现细节,以及 双因素认证 双因素认证的实现细节