Better Auth 연동
이 플러그인의 설치 단계와 전체 마크다운 가이드가 포함된 설정 프롬프트를 복사하세요.
개요
“개요” 섹션Better Auth는 다음 환경에서 잘 동작합니다 @capgo/capacitor-social-login 디바이스에서 네이티브 로그인 기능을 사용하되, Better Auth가 백엔드에서 세션을 생성하고 관리하기를 원할 때
이 페이지는 가장 적합한 두 가지 통합 패턴에 초점을 맞춥니다:
- Google, Apple, Facebook을 위한 네이티브 토큰 핸드오프
- Auth0, Okta, Keycloak 및 커스텀 OIDC 서버와 같은 제공자를 위한 Better Auth Generic OAuth
사용할 패턴 선택
섹션 제목: “어떤 패턴을 사용할 것인가”Native token handoff 사용
“네이티브 토큰 핸드오프 사용” 섹션사용 SocialLogin.login() 먼저 실행한 다음, 반환된 토큰을 Better Auth로 보내세요: authClient.signIn.social() 다음 기능을 사용할 때:
- Apple
Better Auth Generic OAuth 사용
“Better Auth Generic 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 클라이언트 패키지를 사용하세요. 토큰 전달 패턴은 동일합니다.
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 - 액세스 토큰 플로우: 액세스 토큰을 둘 다로 전달하세요
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' }).
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 프로바이더 예시
“Better Auth Generic OAuth 프로바이더 예시” 섹션Better Auth는 여러 프로바이더용 헬퍼를 미리 구성해 제공합니다. 이는 social-login 플러그인 문서에 나오는 추가 프로바이더 예시와 가장 비슷합니다.
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',});수동 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',});참고 및 주의사항
“참고 및 주의사항” 섹션-
Google 온라인 모드 사용 Better Auth에는
idToken이 필요하므로google.mode: 'offline'이 이 핸드오프 플로우에는 적합하지 않습니다. -
Apple nonce 재사용 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의 구현 세부 사항은, 2단계 인증 2단계 인증의 구현 세부 사항에 대해서는