
개요
안드로이드에서 쿠키를 다룰 때는 보통 두 가지 상황이 있다.
WebView안에서 웹 세션을 유지해야 하는 경우- 앱의 HTTP 통신에서 쿠키를 직접 관리해야 하는 경우
실무에서는 대부분 첫 번째, 즉 WebView 쿠키 처리가 더 자주 문제를 만든다.
로그인 세션이 유지되지 않거나, 웹에서 발급한 쿠키를 앱이 미리 넣어줘야 하거나, 서드파티 쿠키 때문에 인증이 깨지는 경우가 대표적이다.
이 글에서는 다음 내용을 정리한다.
- Android
WebView에서 쿠키를 사용하는 방법 CookieManager로 쿠키를 설정, 조회, 삭제하는 방법flush()와CookieSyncManager의 차이- 서드파티 쿠키와 파일 스킴 쿠키 주의사항
- 앱 네트워크 통신에서의 쿠키 관리 기본 예시
Android 에서 쿠키를 다루는 핵심 클래스
안드로이드 공식 문서 기준으로 android.webkit.CookieManager 는 애플리케이션의 WebView 인스턴스가 사용하는 쿠키를 관리한다.
즉 WebView 관련 쿠키는 보통 이 클래스로 다룬다.
val cookieManager = CookieManager.getInstance() |
중요한 점은 이 클래스가 생성자 사용 대상이 아니라는 점이다.
공식 문서도 직접 생성하지 말고 getInstance() 로 singleton 을 가져오라고 안내한다.
가장 기본적인 설정
WebView 에서 쿠키를 정상적으로 쓰려면 보통 아래 설정부터 확인한다.
val webView: WebView = findViewById(R.id.webView) |
setAcceptCookie(true) 는 WebView 가 쿠키를 보내고 받을 수 있게 한다.
공식 문서 기준 기본값은 true 이지만, 명시적으로 써 두면 의도가 분명해진다.
WebView 에 쿠키를 직접 넣는 방법
앱에서 로그인 토큰이나 세션 쿠키를 먼저 알고 있고, 그 값을 WebView 에 주입하고 싶을 때가 있다.
예를 들어:
- 앱 로그인 후 같은 세션으로 웹 페이지를 열고 싶을 때
- SSO 연동 시 웹에 쿠키를 미리 넣어야 할 때
- 특정 도메인에 세션 쿠키를 세팅한 뒤
loadUrl()해야 할 때
이때는 setCookie() 를 사용한다.
val url = "https://example.com" |
여기서 중요한 포인트는 다음이다.
- 쿠키는 대상 URL 기준으로 설정한다.
- 보통
loadUrl()전에 넣는 편이 안전하다. - 저장 내용을 디스크까지 반영하고 싶으면
flush()를 호출한다.
즉 “쿠키 넣기 -> flush -> loadUrl” 순서를 기억해 두면 된다.
비동기 setCookie() 예제
API 21 이상에서는 callback 을 받는 setCookie() 도 사용할 수 있다.
val url = "https://example.com" |
이 방식은 쿠키 설정 성공 여부를 확인하고 그 다음 동작을 이어가고 싶을 때 유용하다.
예를 들어:
- 쿠키 주입이 끝난 뒤에만 페이지를 열고 싶을 때
- 로그인 브릿지 흐름에서 순서를 보장하고 싶을 때
현재 쿠키 조회하기
특정 URL 에 어떤 쿠키가 들어 있는지 확인하고 싶다면 getCookie() 를 사용한다.
val cookies = CookieManager.getInstance().getCookie("https://example.com") |
반환 값은 보통 HTTP Cookie 헤더 형태의 문자열이다.
예:
sessionId=abc123; accessToken=token-value |
디버깅할 때는 편리하지만, 운영 로그에 민감한 쿠키 값을 그대로 남기지 않도록 주의해야 한다.
쿠키 삭제하기
로그아웃 처리나 세션 초기화가 필요하면 쿠키 삭제가 필요하다.
모든 쿠키 삭제
공식 문서 기준 removeAllCookie() 는 deprecated 이고, API 21 이상에서는 removeAllCookies() 를 사용해야 한다.
val cookieManager = CookieManager.getInstance() |
이 메서드는 비동기다.
즉 삭제 직후 바로 다음 작업을 하면 타이밍 이슈가 생길 수 있으므로 callback 이후에 후속 처리를 하는 편이 좋다.
세션 쿠키만 삭제
세션 쿠키만 지우고 싶다면:
CookieManager.getInstance().removeSessionCookies { removed -> |
로그아웃 시 영속 쿠키까지 모두 지울지, 세션 쿠키만 지울지는 서비스 정책에 따라 다르다.
flush() 는 왜 필요한가
공식 문서 기준 flush() 는 현재 getCookie() API 로 접근 가능한 쿠키를 영구 저장소에 기록하도록 보장한다.
CookieManager.getInstance().flush() |
즉 메모리에만 반영된 쿠키를 디스크에도 반영하고 싶을 때 호출하는 메서드라고 이해하면 된다.
다음 상황에서 특히 자주 쓴다.
- 앱이 종료되기 전에 쿠키를 저장하고 싶을 때
- 쿠키를 세팅한 직후 안정적으로 반영하고 싶을 때
- 로그아웃 후 삭제 상태를 확실히 반영하고 싶을 때
CookieSyncManager 는 더 이상 쓰지 않는다
예전 안드로이드 예제에는 CookieSyncManager 코드가 많이 나온다.
하지만 공식 문서 기준 이 클래스는 API 21 에서 deprecated 되었고, 이제는 WebView 가 쿠키를 자동으로 sync 한다.
즉 예전 방식:
// 더 이상 권장되지 않음 |
대신 지금은:
CookieManager.getInstance().flush() |
를 쓰는 것이 맞다.
서드파티 쿠키 허용
공식 문서 기준 setAcceptThirdPartyCookies() 는 WebView 별 정책이다.
즉 앱 전체 공통 설정이 아니라, 각 WebView 인스턴스마다 따로 적용할 수 있다.
val cookieManager = CookieManager.getInstance() |
이 설정이 필요한 대표적인 경우는 다음과 같다.
- 외부 인증 페이지를 iframe 으로 여는 경우
- 결제/SSO/광고 연동처럼 다른 도메인의 쿠키가 필요한 경우
- 웹 로그인은 되는데 특정 인증 흐름만 WebView 에서 실패하는 경우
공식 문서에 따르면:
- 앱이
KITKAT이하를 target 하면 기본적으로 허용 - 앱이
LOLLIPOP이상을 target 하면 기본적으로 비허용
즉 최신 앱에서는 필요한 경우 명시적으로 켜줘야 할 수 있다.
파일 스킴 쿠키는 피하는 편이 좋다
공식 문서 기준 setAcceptFileSchemeCookies() 는 API 30 에서 deprecated 되었고, 보안상 안전하지 않다고 안내한다.
이유는 file:// URL 이 쿠키를 공유하면서 의도하지 않은 노출이 생길 수 있기 때문이다.
즉 이런 방식:
// 권장되지 않음 |
보다는 공식 문서가 권장하는 androidx.webkit.WebViewAssetLoader 방식으로 http(s) 모델에 맞춰 로컬 리소스를 제공하는 편이 좋다.
실전 예제 1: 앱 로그인 후 WebView 에 세션 전달
앱에서 이미 로그인되어 있고, 같은 세션으로 웹 페이지를 열고 싶은 경우의 대표 예제다.
class HybridActivity : AppCompatActivity() { |
이 패턴은 “로그인 API 는 앱이 호출하고, 화면은 WebView 로 보여주는” 하이브리드 앱에서 자주 사용된다.
실전 예제 2: 로그아웃 시 쿠키 초기화
fun logout(webView: WebView) { |
쿠키만 지우고 끝내지 말고, 상황에 따라:
WebViewcache- history
- local storage 처리 여부
도 함께 검토해야 한다.
서비스에 따라 “로그아웃했는데 뒤로 가기로 이전 세션 화면이 보이는” 문제가 여기서 발생하기도 한다.
실전 예제 3: 앱 HTTP 통신에서 쿠키 사용
WebView 말고 앱의 HTTP 통신에서 쿠키를 다루고 싶다면 java.net.CookieManager 를 사용할 수 있다.
안드로이드 공식 문서 기준 이 클래스는 CookieHandler 의 구현체이며, HttpURLConnection 과 함께 사용할 수 있다.
val cookieManager = java.net.CookieManager() |
간단한 예시는 다음과 같다.
val cookieManager = java.net.CookieManager() |
이 경우 서버가 Set-Cookie 를 내려주면 CookieManager 의 CookieStore 에 저장된다.
val store = cookieManager.cookieStore |
다만 여기서 중요한 점은:
android.webkit.CookieManager는WebView용java.net.CookieManager는 앱 HTTP 통신용
이라는 것이다.
즉 둘은 같은 이름이지만 역할이 다르다.
앱 구조에 따라 두 영역을 별도로 맞춰줘야 할 수도 있다.
이 구분은 공식 문서의 클래스 역할 설명을 바탕으로 한 해석이다.
쿠키가 잘 안 먹을 때 점검할 것
실무에서 자주 보는 문제는 대부분 아래 항목에 걸린다.
setCookie()를loadUrl()뒤에 호출하고 있는지flush()를 안 해서 반영 타이밍이 꼬였는지- 도메인/경로가 실제 요청 URL 과 안 맞는지
Secure쿠키인데https가 아닌 URL 을 쓰는지- 서드파티 쿠키가 필요한데
setAcceptThirdPartyCookies()를 안 켰는지 - 로그아웃 시 쿠키만 지우고 캐시/히스토리를 안 지웠는지
- 옛날 예제처럼
CookieSyncManager를 아직 쓰고 있는지
특히 “앱에서는 쿠키 넣었다고 생각하는데 웹은 로그인 안 됨” 문제는 대부분 도메인, 경로, 시점 문제다.
정리
안드로이드에서 쿠키를 사용할 때 핵심은 WebView 쿠키와 앱 HTTP 쿠키를 구분해서 이해하는 것이다.
WebView쿠키는android.webkit.CookieManager- 앱 HTTP 쿠키는
java.net.CookieManager WebView에 쿠키를 넣을 때는 보통setCookie -> flush -> loadUrl- 서드파티 쿠키가 필요한 흐름은 별도 허용 여부 확인
CookieSyncManager는 더 이상 쓰지 않고flush()사용
하이브리드 앱이나 인증 연동이 있는 프로젝트라면 쿠키 처리는 거의 필수로 만나게 된다.
처음부터 도메인, 타이밍, 삭제 정책까지 함께 정리해 두면 디버깅 시간을 크게 줄일 수 있다.
참고
- Android Developers -
android.webkit.CookieManager: https://developer.android.com/reference/android/webkit/CookieManager.html - Android Developers -
android.webkit.CookieSyncManager: https://developer.android.com/reference/android/webkit/CookieSyncManager - Android Developers -
java.net.CookieManager: https://developer.android.com/reference/java/net/CookieManager - AndroidX WebKit -
CookieManagerCompat: https://developer.android.com/reference/androidx/webkit/CookieManagerCompat