본문 바로가기

Better Auth 연동

GitHub

Better Auth는 다음 환경에서 잘 동작합니다 @capgo/capacitor-social-login 디바이스에서 네이티브 로그인 기능을 사용하되, Better Auth가 백엔드에서 세션을 생성하고 관리하기를 원할 때

이 페이지는 가장 적합한 두 가지 통합 패턴에 초점을 맞춥니다:

  • Google, Apple, Facebook을 위한 네이티브 토큰 핸드오프
  • Auth0, Okta, Keycloak 및 커스텀 OIDC 서버와 같은 제공자를 위한 Better Auth Generic OAuth

사용 SocialLogin.login() 먼저 실행한 다음, 반환된 토큰을 Better Auth로 보내세요: authClient.signIn.social() 다음 기능을 사용할 때:

  • Google
  • Apple
  • Facebook

Better Auth Generic OAuth 사용

“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 클라이언트 패키지를 사용하세요. 토큰 전달 패턴은 동일합니다.

네이티브 모바일 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의 경우, 동일한 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',
});

Better Auth는 두 가지 Facebook 핸드오프 모드를 설명합니다:

  • iOS Limited Login: 다음을 전달하세요 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',
});

Better Auth를 사용한 범용 OAuth 제공자

“Better Auth의 Generic OAuth 제공자” 섹션

Auth0, Okta, Keycloak, GitHub, Microsoft Entra ID 및 유사한 제공자의 경우, Better Auth의 Generic OAuth 플러그인이 ...에서 토큰을 전달하는 것보다 보통 더 적합합니다. SocialLogin.login({ provider: 'oauth2' }).

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 프로바이더 예시

“Better Auth Generic OAuth 프로바이더 예시” 섹션

Better Auth는 여러 프로바이더용 헬퍼를 미리 구성해 제공합니다. 이는 social-login 플러그인 문서에 나오는 추가 프로바이더 예시와 가장 비슷합니다.

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',
});
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',
});
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',
});

수동 Generic OAuth 설정을 사용하는 GitHub

“GitHub 수동 Generic OAuth 설정” 섹션

GitHub에는 Generic 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 재사용 nonce를 한 번 생성한 뒤 Apple 네이티브 로그인에 보내고, 같은 값을 Better Auth에도 전송하세요.

  3. 플랫폼별로 Facebook을 다르게 처리 iOS의 Limited Login은 ID token을 제공합니다. 다른 플로우에서는 access token만 받을 수 있습니다.

  4. 특별한 이유가 없다면 Generic OAuth 플로우를 혼합하지 마세요 Better Auth가 OAuth 프로바이더 설정을 관리한다면, 리다이렉트 플로우도 Better Auth가 관리하도록 하세요.

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의 구현 세부 사항은, 2단계 인증 2단계 인증의 구현 세부 사항에 대해서는