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.