앱 소개

오늘 하루 어땠어? 봉봉이가 묻고있어요. 귀엽고 포근한 리트리버 강아지 봉봉이가 사용자의 일기를 읽고 답장을 보내주는 앱, Hearu예요.
개요
Google Cloud Console에는 Google OAuth 설정을 할 수 있어요. 제가 해놓은 설정이 아니라서 설정을 수정했어요. 근데 설정을 수정한 이후에 릴리즈 된 앱의 Google OAuth가 동작을 하지 않게 됐어요. 이번 글에서는 이 문제를 어떻게 해결하였는지 공유하려고 해요.
문제 상황
저는 웹 클라이언트 ID와 release 키스토어에서 뽑은 업로드 키만 등록해 놓으면 릴리즈 환경에서 OAuth 2.0을 사용할 수 있다고 잘못 알고 있었어요. 그리고 클라이언트 ID의 이름이 구분 없이 기본값으로 설정되어서 클라이언트 ID끼리 구분이 안됐고 유일하게 알고 있는건 업로드 키였어요. 그래서 웹 클라이언트와 업로드 키를 제외한 나머지 Android 클라이언트 ID를 전부 삭제를 했었어요.

그러고 나중에 릴리즈 된 저희 앱의 Google 간편 인증 과정에서 다음과 같은 오류가 발생하는 걸 확인했어요.

해당 오류가 왜 발생했는지 분석하기 위해 코드를 확인했어요.
원인 분석
코드를 확인해보니, 구글 로그인 과정에서 NoCredentialException이 발생하는 모든 상황에 대해 "Google 계정을 찾을 수 없습니다. 기기에 Google 계정을 추가해주세요."라는 문구를 반환하도록 되어있었어요.

1. NoCredentialException
Android 공식 트러블 슈팅 가이드는 NoCredentialException("No Matching credentials found")의 원인으로 다음 세가지로 명시했어요.
- setFilterByAuthroizedAccounts가 기기에 인증된 계정이 없는 상태에서 true로 설정된 경우
- 기기에 로그인된 계정이 없는 경우 (계정이 추가되지 않았거나 계정이 재인증을 필요로 하는 경우)
- 기기의 어떤 계정에서든 Sign-in 프롬프트가 비활성화되어 있으면 bottomsheet UI가 나타나지 않는다. 이 전역 설정은 Google Account Settings > Sign in with Google에서 찾을 수 있으며, bottomsheet UI가 표시되려면 활성화되어 있어야 한다. (단, 버튼 플로우에는 영향을 주지 않음)
보충 케이스
위 공식 원인 외에 실무에서 자주 동반되는 케이스도 있어요.
- Google Play Services 데이터 손상: 유효한 Google 계정이 존재해도 Play Services 데이터가 손상되면 NoCredentialException이 발생할 수 있다. 이 경우 Play Services 캐시/데이터 삭제, 계정 재등록, 기기 재시작 등이 해결책이 된다.
- serverClientId 오설정: Web client ID(서버용 OAuth 클라이언트 ID)를 잘못 넣으면 매칭되는 자격 증명을 못 찾아 동일 예외로 이어질 수 있다.
그런데 우리 경우는 어디에도 없었다
우리 앱에서 발생한 문제는 공식 가이드의 세 가지 원인에도, 실무에서 자주 동반되는 케이스에도 해당하지 않았어요.
- 기기에 Google 계정은 멀쩡히 로그인되어 있었어요. → 1, 2번 아님
- Sign-in 프롬프트도 켜져 있었어요. → 3번 아님
- setFilterByAuthorizedAccounts는 false로 두고 있었어요. → 1번 재확인 아님
- Play Services도 정상이고 serverClientId(Web client ID)도 올바르게 넣었어요. → 보충 케이스 아님
그래도 한 가지는 확실했어요. NoCredentialException은 이름 그대로 "매칭되는 자격 증명을 못찾았다"면 자격 증명 후보가 0개로 집계되는 어떤 단계가 있다는 뜻이에요. 그래서 그 단계를 찾아봤어요.
2. Sign in with Google 동작 방식
정의
Sign in with Google은 사용자가 자기 구글 계정으로 앱이나 웹사이트에 로그인할 수 있게 해주는 구글의 인증 서비스예요. "구글로 로그인", "Google 간편 로그인" 버튼이 그거예요. 사용자가 앱마다 새로 아이디·비밀번호를 만들 필요 없이, 이미 가진 구글 계정으로 한 번에 로그인하는 방식이죠.
동작 흐름
사용자가 "Google로 로그인" 탭
→ 구글 계정 선택 화면 표시
→ 사용자가 계정 선택 / 동의
→ 구글이 "이 사람 맞다"는 증표(ID 토큰)를 앱에 발급
→ 앱이 그 토큰을 받아 로그인 처리
여기서 앱이 받는 ID 토큰은 "이 사용자는 구글이 확인한 진짜 사람이다."라는 내용을 구글이 서명해서 보증한 정보에요.
SHA-1 등록이 필요한 이유
구글 입장에선 "토큰을 요청하는 이 앱이 정말 등록된 그 앱이 맞는지" 확인해야 해요. 아무 앱이나 토큰을 받아가면 안되니깐요. 안드로이드에서 이 신뢰 검증을 하는 방식이 바로 패키지명 + 서명 키 SHA-1 지문이 조합이에요. GCP에 등록된 지문과 실제 앱을 서명한 키의 지문이 일치해야 그 앱이 정당한 클라이언트로 인정돼요.
즉, SHA-1이 안맞으면 신뢰 검증을 통과 못하고, 결국 "내줄 자격 증명 후보 없음" -> NoCredentialException으로 이어져요.
그렇다면 남은 건 하나에요. 우리 앱은 실제로 어떤 키로 서명돼 있을까? 여기서 Play App Signing이 등장해요.
3. 진짜 원인: Play App Signing의 앱 서명 키
정의
Play App Signing은 안드로이드 앱의 최종 서명 키를 개발자 대신 Google이 보관·관리해주는 기능이에요. 구글 플레이에 앱을 올릴 때 사용하는 방식이고, 지금은 신규 앱 등록 시 기본으로 권장됩니다.
핵심
키가 두 개로 나뉘어요.
- 업로드 키(upload key): 개발자가 AAB를 플레이에 올릴 때 본인 확인용으로 쓰는 키. 이건 개발자가 직접 가지고 있어요. 잃어버려도 Google에 재설정 요청이 가능해요.
- 앱 서명 키(app signing key): Google이 보관하는 키. 사용자에게 실제로 배포되는 APK를 최종 서명하는 키예요.
흐름
개발자가 AAB 빌드 → [업로드 키로 서명] → 플레이에 업로드
→ Google이 업로드 키 확인 → 서명 제거
→ [앱 서명 키로 재서명] → 사용자 기기에 설치되는 APK
즉 트랙에 올라가 설치되는 APK는 내 업로드 키가 아니라 Google의 앱 서명 키로 재서명된 것이에요. 그러면 검증 기준이 되는 SHA-1도 앱 서명 키 쪽이 돼요.
우리가 GCP에 등록해둔 건 업로드 키의 SHA-1뿐이었어요. 앞서 삭제한 클라이언트 ID에 앱 서명 키 SHA-1이 포함되었던 거죠. 그래서:
- 릴리즈 트랙 빌드 → Google이 앱 서명 키로 재서명 → 그 SHA-1이 GCP에 없음 → 검증 실패 → 후보 0개 → NoCredentialException (실제 겪은 증상)
공식 가이드 어디에도 없던 이유가 분명해졌어요. 가이드의 원인들은 전부 "기기/계정 상태" 문제인데, 저희 건 OAuth 클라이언트 구성(SHA-1 등록) 문제였어요. 분류 축 자체가 달랐어요.
4. 해결 방안: 앱 서명 키 SHA-1 등록
트랙 빌드를 실제로 서명하는 앱 서명 키의 SHA-1을 GCP에 추가 등록하면 돼요.
앱 서명 키 확인하는 방법
Google Play Console에 접속 → 홈 화면 앱 선택 → Google Play로 보호됨 → Play 스토어 보호 → 앱 서명 키 보호 선택

앱 서명 관리에서 SHA-1 인증서 지문을 찾을 수 있어요.

GCP에 등록
등록 방법은 Google Cloud Console → API 및 서비스 → 사용자 인증 정보 → 사용자 인증 정보 만들기 → OAuth 클라이언트 ID 선택

이름, 패키지명, SHA-1 인증서 지문을 입력 후, 만들기 버튼을 누르면 클라이언트 ID가 생성돼요.

문제의 발단이었던 클라이언트 ID들을 생성했어요. 각 환경 별로 어떤 클라이언트 ID를 만들어야하는지 알지 못했던 것도 있지만, 클라이언트 ID 이름이 전부 비슷해서 직관적으로 바로 알 수 없었어요. 그래서 각 클라이언트 ID가 어디에서 사용되는지 직관적으로 파악하기 위해 이름을 명확하게 해줬어요.

결론
앱 서명 키의 SHA-1을 GCP에 등록한 뒤 릴리즈 앱을 다시 배포해보니, Google 간편 인증이 정상적으로 동작했어요.
Play App Signing을 켜면 키가 업로드 키와 앱 서명 키 둘로 나뉘고, 실제 기기에 설치되는 APK는 Google이 재서명한 앱 서명 키로 서명된다는 사실이 핵심이었어요. GCP에 업로드 키 SHA-1만 등록해두면, 정작 설치된 앱의 서명과 매칭되지 않아 자격 증명 후보가 0개가 되는 거예요.
설정 하나 잘못 지운 일에서 시작됐지만, 덕분에 Sign in with Google이 어떤 신뢰 검증을 거치는지 제대로 이해하게 됐어요.
'Side Project > Hearu' 카테고리의 다른 글
| Google Play Console 앱 이전 방법 | Hearu 프로젝트 (1) | 2026.05.30 |
|---|---|
| 해지 된 Google Play Console 계정에 계정 등록 결제했을 때 환불 받는 방법 | Hearu 프로젝트 (0) | 2026.05.28 |
| 테스트 코드 도입 배경기 | Hearu 프로젝트 (0) | 2026.05.27 |
| API 설계에서의 멱등성 문제 해결 | Hearu 프로젝트 (0) | 2026.05.25 |
| 로그 레벨 설정 | Hearu 프로젝트 (0) | 2026.05.23 |