Skip to content

Authentication — Native SDK Implementation ​

Status: Active Last updated: 2026-03-27 Supersedes: api-kakao.md (deprecated)


Architecture ​

All social login providers use their native SDKs to obtain an ID token, then exchange it with Supabase via signInWithIdToken. This is the correct approach per Supabase, Kakao, Google, and Apple documentation.

Login Screen → Native SDK login() → idToken → supabase.signInWithIdToken()
                                                      ↓
                                              Supabase Auth Server
                                              - Validates JWT via JWKS
                                              - Checks aud matches Client ID
                                              - Creates/links user
                                              - Returns session tokens
                                                      ↓
                                              DB trigger: handle_new_user()
                                              - Auto-creates profiles row
                                              - Pulls name from OAuth metadata

No browser-based OAuth. Native SDKs provide the official branded UI, handle biometrics/passkeys, and are required by App Store guidelines.


Providers ​

Kakao (Primary — Korean market) ​

Current SDK: @react-native-seoul/kakao-login in packages/app/src/adapters/supabase/auth.supabase.ts.

Target SDK: @react-native-kakao/core + @react-native-kakao/user after the auth rebuild slice. Do not treat the current @react-native-kakao/core share-plugin wiring in apps/mobile/app.config.js as proof that Kakao auth has migrated.

Flow:

  1. Native Kakao SDK login opens KakaoTalk or Kakao Account fallback.
  2. Current adapter calls the login bridge from @react-native-seoul/kakao-login.
  3. Returns { idToken, accessToken, ... } (idToken requires OIDC enabled)
  4. supabase.auth.signInWithIdToken({ provider: 'kakao', token: idToken })

Supabase Dashboard:

  • Client ID: Kakao Native App Key.
  • Client Secret: configure in Supabase/Kakao dashboard or environment only; do not commit secrets into docs.

Kakao Developers Console:

  • OpenID Connect: ON
  • Platform > Android: package com.ivorybridge.twomore + key hash from getKeyHashAndroid()
  • Platform > iOS: bundle com.ivorybridge.twomore

Current gap: production Kakao auth credentials and native config proof remain external blockers. The @react-native-kakao/core plugin currently added through apps/mobile/app.config.js is for Kakao Share and is gated by TWOMORE_KAKAO_NATIVE_APP_KEY, with EXPO_PUBLIC_KAKAO_APP_KEY accepted as the backward-compatible fallback when it carries the same Kakao Native App Key.

Google ​

SDK: @react-native-google-signin/google-signin

Flow:

  1. GoogleSignin.configure({ webClientId }) at app startup
  2. GoogleSignin.signIn() → native Google sign-in UI
  3. Returns { data: { idToken } }
  4. supabase.auth.signInWithIdToken({ provider: 'google', token: idToken })

Supabase Dashboard:

  • Client ID: Web Client ID
  • Authorized Client IDs: WEB_ID,IOS_ID,ANDROID_ID

Google Cloud Console:

  • 3 OAuth Client IDs: Web, iOS (bundle), Android (package + SHA-1)

Apple (iOS only) ​

SDK: expo-apple-authentication

Flow:

  1. AppleAuthentication.signInAsync({ requestedScopes: [FULL_NAME, EMAIL] })
  2. Returns { identityToken, fullName }
  3. supabase.auth.signInWithIdToken({ provider: 'apple', token: identityToken })
  4. Save fullName immediately (Apple only sends on first sign-in)

Supabase Dashboard:

  • Client ID: Bundle ID (com.ivorybridge.twomore)

Android: Not available natively. Don't show button on Android.


Supabase Client ID Quick Reference ​

ProviderSupabase "Client ID"Why
KakaoNative App KeySDK sets aud to Native App Key
GoogleWeb Client IDGoogle sets aud to Web Client ID
AppleBundle IDApple sets aud to bundle/service ID

Hex Architecture ​

Domain:     OAuthProvider ('kakao' | 'google' | 'apple')
Port:       AuthServicePort.signInWithProvider(provider)
Adapter:    Routes to native SDK → signInWithIdToken
Hook:       useAuth().signInWithProvider(provider)
Screen:     Branded provider buttons
Guard:      AuthGuard → isAuthenticated + onboardingCompletedAt

Adding a New Provider ​

  1. Add to OAuthProvider in packages/app/src/domain/entities/auth.entity.ts
  2. Install native SDK
  3. Add initialization to app/_layout.tsx
  4. Add case to adapter's signInWithProvider
  5. Configure in Supabase Dashboard
  6. Add branded button to login screen
  7. Add i18n string

Key Files ​

FilePurpose
packages/app/src/domain/entities/auth.entity.tsOAuthProvider type
src/ports/services/auth.service.port.tsAuth port
packages/app/src/adapters/supabase/auth.supabase.tsNative SDK routing
packages/app/src/presentation/hooks/use-auth.tsAuth hook
packages/app/src/presentation/screens/auth/login-screen.tsxLogin UI
apps/mobile/app.config.jsKakao Share native plugin/env wiring; not Kakao auth proof
supabase/migrations/00045_auto_create_profile.sqlProfile trigger

Markdown remains the source of truth. Run yarn docs:check before handoff.