웹뷰에서 카카오/구글 OAuth가 안 되는 이유, 구조부터 짚어드립니다

"PC에선 잘 되는데 앱에서만 흰 화면이 떠요"라는 문의가 정말 많아요. 웹뷰 앱 만들 때 가장 자주 부딪히는 문제 중 하나입니다. 단순히 코드 추가의 문제가 아니라 OAuth 표준과 모바일 OS의 충돌이라는 구조적 이슈예요. 본질부터 짚으면 해결도 쉬워집니다.

7분 소요

DEEP DEBUG

웹뷰에서 카카오/구글 OAuth가 안 되는 이유, 구조부터 짚어드립니다

"PC에선 잘 되는데 앱에서만 흰 화면이 떠요"라는 문의가 정말 많아요. 웹뷰 앱 만들 때 가장 자주 부딪히는 문제 중 하나입니다. 단순히 코드 추가의 문제가 아니라 OAuth 표준과 모바일 OS의 충돌이라는 구조적 이슈예요. 본질부터 짚으면 해결도 쉬워집니다.

결론을 미리 말씀드리면, 이 문제의 근본 원인은 "웹뷰는 외부 앱(카카오톡)을 직접 실행할 권한이 없다"는 데 있습니다. PC 브라우저는 이걸 자동 처리하지만, 모바일 웹뷰는 명시적으로 코드를 추가해야 처리돼요. 그래서 PC는 되는데 앱은 안 되는 거예요.

또한 구글은 2021년부터 보안 이유로 웹뷰의 OAuth 사용을 공식적으로 제한합니다. 즉, 카카오와 구글은 다른 차원의 문제예요. 카카오는 처리 코드 추가로 해결되지만, 구글은 Chrome Custom Tabs로 우회해야 합니다. 이 차이를 모르고 같은 방식으로 접근하면 구글 로그인은 절대 작동 안 해요.

먼저 OAuth 흐름이 웹뷰에서 어떻게 깨지는지

PC 브라우저와 모바일 웹뷰의 OAuth 흐름 차이를 보면 문제의 본질이 보입니다. 같은 OAuth 표준인데 왜 모바일에서만 깨지는지 이해되실 거예요.

OAuth 흐름의 차이
PC 브라우저 ✓
1. 카카오 로그인 버튼 클릭

2. 카카오 인증 페이지 호출

3. 인가코드 → redirect URI 리턴

로그인 성공
모바일 웹뷰 ✗
1. 카카오 로그인 버튼 클릭

2. intent:// URL 호출 시도
(카카오톡 앱 실행)

웹뷰는 intent URI 처리 불가
웹뷰는 외부 앱 실행 권한 없음
→ 흰 화면

핵심은 2번 단계예요. 카카오 SDK는 카카오톡 앱을 실행하기 위해 intent:// URL scheme을 호출하는데, 웹뷰는 기본적으로 이런 URL을 처리하는 권한이 없습니다. 그래서 클릭해도 아무 일도 안 일어나거나 흰 화면만 떠요.

이걸 해결하려면 웹뷰의 URL 처리 로직을 직접 오버라이드해서 "intent:// URL이 오면 외부 앱을 실행하도록" 명시적으로 코드를 추가해야 합니다. 그래서 카카오는 공식 문서에서 두 가지 작업을 안내해요.

카카오 OAuth 해결법: 두 가지 작업

카카오 측에서 명시한 해결책은 "카카오톡 실행 처리""팝업 웹뷰 처리" 두 가지를 모두 추가하는 것입니다. 둘 중 하나만 하면 부분적으로만 작동해요.

작업 1: 카카오톡 앱 실행 처리 (Android)

웹뷰의 shouldOverrideUrlLoading 메서드를 오버라이드해서, intent URI가 호출되면 직접 파싱해 카카오톡 앱을 실행해야 합니다.

// Android Kotlin 예시
override fun shouldOverrideUrlLoading(
  view: WebView, request: WebResourceRequest
): Boolean {
  val url = request.url.toString()
  if (url.startsWith("intent://")) {
    val intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME)
    view.context.startActivity(intent)
    return true
  }
  return false
}
주의: 카카오톡이 설치 안 된 기기에서는 ActivityNotFoundException이 발생합니다. try-catch로 감싸서 미설치 시 카카오 계정 로그인 페이지로 fallback 처리 필수예요. 안 그러면 앱이 죽어요.

작업 2: 팝업 웹뷰 처리 (window.open)

카카오 JavaScript SDK는 보안 향상을 위해 일부 기능에서 팝업 윈도우를 사용합니다. 웹뷰가 window.open()을 처리하지 못하면 클릭해도 아무 일도 안 일어나요. 이게 두 번째 사고 지점입니다.

// 부모 웹뷰 설정
webView.settings.run {
  javaScriptEnabled = true
  javaScriptCanOpenWindowsAutomatically = true
  setSupportMultipleWindows(true) // 핵심!
}
 
// onCreateWindow에서 자식 웹뷰 생성
override fun onCreateWindow(...): Boolean {
  val childWebView = WebView(view.context)
  // 부모와 동일한 설정 적용
  // transport.webView = childWebView
  // resultMsg.sendToTarget()
  return true
}

iOS WKWebView 처리

iOS는 Android와 메서드 이름만 다를 뿐 처리 원리는 동일합니다. decidePolicyFor navigationAction에서 URL scheme 분기.

// iOS Swift 예시
func webView(_ webView: WKWebView,
  decidePolicyFor navigationAction: WKNavigationAction,
  decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
  guard let url = navigationAction.request.url else { return }
  if url.scheme == "kakaotalk" || url.scheme == "kakaolink" {
    UIApplication.shared.open(url)
    decisionHandler(.cancel)
    return
  }
  decisionHandler(.allow)
}

구글 OAuth는 다릅니다: Chrome Custom Tabs로 우회

카카오는 위 처리로 해결되지만, 구글은 다른 차원의 문제입니다. 구글은 2016년부터 보안 이유로 웹뷰에서의 OAuth 사용을 공식적으로 제한해왔고, 2021년부터는 점차 차단을 강화하고 있어요.

⚠️ 구글의 공식 입장
구글 측 메시지: "WebView에서 인증에 OAuth를 사용하면 앱이 보안 문제에 취약해질 수 있으며, 싱글 사인온(SSO) 세션에서 사용자의 연결이 끊겨 사용성이 저하될 수 있습니다."
구글의 권고: Chrome Custom Tabs(Android) / SFSafariViewController(iOS)로 교체하세요.

Chrome Custom Tabs는 웹뷰가 아니라 진짜 Chrome 브라우저예요. 사용자의 기존 구글 로그인 세션을 그대로 활용할 수 있고, 보안 표준도 만족합니다. 화면 전환은 거의 자연스럽게 보이고요.

Android Custom Tabs 사용 예시:

// 구글 OAuth는 웹뷰 대신 Custom Tabs로
val customTabsIntent = CustomTabsIntent.Builder()
  .setShowTitle(true)
  .build()
customTabsIntent.launchUrl(context,
  Uri.parse("https://accounts.google.com/o/oauth2/v2/auth?..."))

실전 디버깅: 흰 화면 만났을 때 체크 순서

실제로 트러블슈팅 할 때의 체크 순서입니다. 위에서부터 차례로 확인하세요. 5분 안에 원인 90%는 잡힙니다.

STEP 1
Chrome inspect로 웹뷰 디버깅 활성화
Android는 chrome://inspect로 실제 웹뷰 콘솔 로그 확인 가능. iOS는 Safari → 개발 메뉴. 흰 화면의 99%는 콘솔에 에러 메시지가 있어요. 콘솔 안 보고 추측하면 시간만 낭비됩니다.
STEP 2
Network 탭에서 redirect 흐름 추적
로그인 클릭 → 카카오 → redirect URI까지 어디서 끊기는지 확인. intent:// 호출 시점에서 멈췄다면 shouldOverrideUrlLoading 미구현. URL이 끊긴 지점 = 문제 발생 지점.
STEP 3
redirect URI가 카카오 콘솔에 등록됐는지
"KOE006" 에러 → redirect URI 미등록. 카카오 디벨로퍼스 콘솔의 카카오 로그인 → 리다이렉트 URI에 정확한 값 등록. 콘솔 등록 값과 코드의 redirect_uri가 한 글자도 다르면 안 됩니다.
STEP 4
window.open 처리가 됐는지 확인
팝업 화면 클릭 시 화면이 안 뜨면 setSupportMultipleWindows(true) 누락. Android는 onCreateWindow 오버라이드 필수.
STEP 5
User-Agent 확인 (구글의 경우)
"disallowed_useragent" 에러 → 구글이 웹뷰를 감지하고 차단한 것. Custom Tabs로 전환 외엔 우회 방법 없음.

자주 만나는 에러 코드 빠른 참조

실전에서 자주 만나는 에러 코드와 의미를 정리했어요. 에러 메시지에 이 코드가 보이면 즉시 해결 방향을 잡을 수 있어요.

코드
제공자
의미와 해결
KOE006
카카오
redirect URI 불일치 → 콘솔 등록 확인
KOE101
카카오
앱 키 오류 → REST API 키 확인
KOE237
카카오
요청 수 초과 → Rate limit 정책 확인
disallowed_useragent
구글
웹뷰에서 차단 → Custom Tabs 전환 필수
redirect_uri_mismatch
구글
콘솔 redirect URI 미등록 → GCP 콘솔 확인
access_denied
공통
사용자가 동의 거부 → 정상 흐름

웹뷰 OAuth의 근본적 대안: 네이티브 SDK 직접 사용

사실 가장 깔끔한 해결책은 웹뷰에서 OAuth를 처리하지 않고, 네이티브 SDK로 처리한 토큰을 웹뷰에 전달하는 방식입니다. 구조가 살짝 복잡해지지만 한 번 만들어두면 이후 OAuth 정책 변화에 흔들리지 않아요.

흐름:
1. 웹뷰 → 네이티브 (JavaScript Bridge로 "로그인 시작" 신호)
2. 네이티브 → 카카오 / 구글 SDK로 OAuth 처리
3. 네이티브가 access_token / 사용자 정보 받음
4. 네이티브 → 웹뷰 (토큰 전달, evaluateJavaScript)
5. 웹뷰가 토큰으로 자체 서버에 로그인 처리
장점: 웹뷰 OAuth의 모든 문제(intent URL, window.open, 구글 차단)에서 자유로움. 사용자 경험도 가장 자연스러움. 카카오톡이 설치된 사용자는 SSO도 가능.
단점: JavaScript Bridge 통신 코드 추가 필요. iOS / Android 양쪽 동일하게 구현해야 함. 기존 웹 코드 일부 수정 필요.

정리하며

웹뷰 OAuth 문제의 본질은 "브라우저는 자동으로 처리하지만 웹뷰는 명시적으로 처리해야 한다"는 점입니다. 이걸 알면 모든 트러블슈팅이 쉬워져요. PC에서 잘 되니까 코드 문제가 없을 거라고 생각하면 안 돼요. 모바일 웹뷰는 PC 브라우저와 다른 환경입니다.

제가 가장 강조하고 싶은 건 이거예요. 카카오는 처리, 구글은 우회입니다. 카카오는 위에서 설명한 두 가지 처리(intent 처리, window.open 처리)로 해결되지만, 구글은 Custom Tabs 외에는 답이 없어요. 같은 방식으로 접근하면 시간만 낭비합니다.

한 가지 팁을 더 드리면, 앱 시작부터 네이티브 SDK + JavaScript Bridge 구조로 가시면 위 모든 고민이 사라집니다. 처음에는 약간 복잡해 보이지만, 1년 후 OAuth 정책 변화에 흔들리지 않는 견고한 구조가 돼요. 웹뷰 + OAuth는 어차피 임시방편이라는 점, 인지하고 시작하시는 게 좋습니다.

WebView OAuth 트러블슈팅 · 시니어 개발자 가이드
앱 개발이 고민되시나요?

기획부터 출시까지, 모바일파트너스가 함께합니다

다른 아티클 살펴보기

구글플레이 정책 놓치면 앱이 사라집니다

Play Console 메일을 안 본 사이 앱이 사라진 회사를 봤습니다. Target API 35부터 Age Signals API까지 2025-2026 정책을 한 번에 정리했습니다.

구글플레이 정책 놓치면 앱이 사라집니다

Play Console 메일을 안 본 사이 앱이 사라진 회사를 봤습니다. Target API 35부터 Age Signals API까지 2025-2026 정책을 한 번에 정리했습니다.

앱 출시 일정 단축하기, 결론부터 말씀드리면 이렇습니다

"마케팅 캠페인이 다음 주 시작인데 앱 심사가 안 끝나요"라는 다급한 상담을 정말 많이 받습니다. 이게 단순한 기술 문제가 아니에요. 출시 일정 지연은 마케팅 비용, 매출, 투자자 일정까지 영향을 미치는 비즈니스 리스크입니다. 그래서 일정 단축은 의사결정 문제로 접근해야 합니다.

앱 출시 일정 단축하기, 결론부터 말씀드리면 이렇습니다

"마케팅 캠페인이 다음 주 시작인데 앱 심사가 안 끝나요"라는 다급한 상담을 정말 많이 받습니다. 이게 단순한 기술 문제가 아니에요. 출시 일정 지연은 마케팅 비용, 매출, 투자자 일정까지 영향을 미치는 비즈니스 리스크입니다. 그래서 일정 단축은 의사결정 문제로 접근해야 합니다.

웹뷰에서 카카오/구글 OAuth가 안 되는 이유, 구조부터 짚어드립니다

"PC에선 잘 되는데 앱에서만 흰 화면이 떠요"라는 문의가 정말 많아요. 웹뷰 앱 만들 때 가장 자주 부딪히는 문제 중 하나입니다. 단순히 코드 추가의 문제가 아니라 OAuth 표준과 모바일 OS의 충돌이라는 구조적 이슈예요. 본질부터 짚으면 해결도 쉬워집니다.

웹뷰에서 카카오/구글 OAuth가 안 되는 이유, 구조부터 짚어드립니다

"PC에선 잘 되는데 앱에서만 흰 화면이 떠요"라는 문의가 정말 많아요. 웹뷰 앱 만들 때 가장 자주 부딪히는 문제 중 하나입니다. 단순히 코드 추가의 문제가 아니라 OAuth 표준과 모바일 OS의 충돌이라는 구조적 이슈예요. 본질부터 짚으면 해결도 쉬워집니다.

(주)모바일파트너즈

서울 마포구 월드컵로 196, 대명비첸시티 14층

MobilePartners
모바일파트너스 로고

Contact

develop@mobpa.co.kr

© 2025 MobilePartners. All rights reserved

(주)모바일파트너즈

서울 마포구 월드컵로 196, 대명비첸시티 14층

Contact

develop@mobpa.co.kr

© 2025 MobilePartners. All rights reserved

(주)모바일파트너즈

서울 마포구 월드컵로 196, 대명비첸시티 14층

Contact

develop@mobpa.co.kr

© 2025 MobilePartners. All rights reserved