블로그로 돌아가기

여러 앱에서 하나의 Google 로그인을 공유하는 법 (Supabase + Flutter)

TL;DR

Supabase에는 Web Client ID 하나만 등록한다. Android/iOS 클라이언트는 Google Cloud Console에만 등록하면 되고, Supabase는 건드릴 필요가 없다. 앱이 100개여도 동일하다.


문제 상황

"Just Apps"라는 플랫폼을 만들고 있다. Just QR, Just Notes 등 여러 앱을 하나의 계정 시스템으로 운영하고 싶다. 백엔드는 Supabase, 프론트는 Flutter.

처음 든 의문:

Supabase Google Provider에 Client ID를 하나밖에 못 넣는데, 앱이 여러 개면 어떻게 하지?

이 질문 때문에 signInWithOAuth (브라우저 방식)도 시도해봤지만, 커스텀 URL 스킴 제한, Site URL 1개 제한 등으로 모바일 멀티앱 구조에는 맞지 않았다.

결론부터 말하면, 원래 방식(google_sign_in + signInWithIdToken)이 정답이었다.


Google OAuth Client의 구조를 이해하면 풀린다

Google Cloud Console에서 OAuth 클라이언트를 만들 때, 타입이 나뉜다:

타입역할어디에 등록?
Web서버 측 토큰 교환Supabase Provider에 등록
Android앱의 서명 검증Google Cloud Console에만
iOS앱의 번들 검증Google Cloud Console에만

핵심: Supabase에는 Web Client만 등록한다. Android/iOS 클라이언트 ID는 Supabase에 넣는 것이 아니다.


실제 구조

TEXT
Google Cloud 프로젝트 (Just Apps)
├── Web Client (1개)
│   └── Supabase Google Provider에 등록
│   └── 모든 앱의 Flutter 코드에서 serverClientId로 사용
├── Android Client - Just QR 디버그
│   └── 패키지명: com.justkihyun.justqr + 디버그 SHA-1
├── Android Client - Just QR 릴리즈
│   └── 패키지명: com.justkihyun.justqr + 릴리즈 SHA-1
├── Android Client - Just Notes 디버그
│   └── 패키지명: com.justkihyun.justnotes + 디버그 SHA-1
├── Android Client - Just Notes 릴리즈
│   └── 패키지명: com.justkihyun.justnotes + 릴리즈 SHA-1
├── iOS Client - Just QR
│   └── Bundle ID: com.justkihyun.justqr
└── iOS Client - Just Notes
    └── Bundle ID: com.justkihyun.justnotes

흐름

TEXT
[Flutter 앱]
    ├── google_sign_in 패키지로 네이티브 Google 로그인
    │   (Google SDK가 앱의 패키지명 + SHA-1로 Android Client 자동 매칭)
    ├── idToken, accessToken 획득
    └── Supabase signInWithIdToken() 호출
        (Supabase가 Web Client ID + Secret으로 토큰 검증)
        └── 동일한 Supabase 프로젝트 → 동일한 auth.users → 동일한 계정

앱이 달라도 같은 Google 계정으로 로그인하면 같은 Supabase 유저가 된다. Web Client ID가 같기 때문이다.


새 앱 추가할 때 해야 하는 것

  1. Google Cloud Console: Android/iOS 클라이언트 추가 (패키지명 + SHA-1/Bundle ID)
  2. Flutter 코드: 같은 Web Client ID 복붙
  3. Supabase: 같은 프로젝트 URL + anon key 연결

Supabase 설정은 건드릴 것이 없다.


signInWithOAuth는 왜 안 되나

브라우저 기반 OAuth 방식(signInWithOAuth)도 시도해봤다. 결과:

  • Supabase Site URL이 1개만 설정 가능 → 앱이 여러 개면 하나만 콜백 받을 수 있음
  • Redirect URLs에 커스텀 스킴(myapp://) 등록 불가 (http/https만 허용)
  • PKCE 플로우를 써도 근본적인 제한은 동일

모바일 네이티브 앱에서 멀티앱 구조를 운영한다면, google_sign_in + signInWithIdToken 조합이 유일한 선택지다.


흔한 오해

"앱마다 Supabase에 Client ID를 등록해야 하는 거 아닌가요?"

아니다. Supabase는 Web Client만 안다. Android/iOS 클라이언트는 Google Cloud Console에서만 관리한다. Google SDK가 앱 서명을 검증하는 용도이지, Supabase가 사용하는 것이 아니다.

"ApiException: 10 에러가 나는데요?"

디버그 SHA-1이 Google Cloud Console에 등록되지 않았다. keytool로 SHA-1을 확인하고 Android 클라이언트를 추가하면 된다.

Bash
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android

결론

질문
Supabase에 뭘 등록?Web Client ID 1개
앱마다 추가 설정?Google Cloud Console에 Android/iOS 클라이언트 추가
Supabase 설정 변경?없음
계정 공유?같은 Supabase 프로젝트면 자동 공유
약관 동의 공유?user_agreements 같은 테이블을 공유하면 됨

복잡하게 생각할 것 없다. Google이 설계한 대로 쓰면 된다.

댓글