Android/study

[Android] WebView 쿠키에 관하여 ... 🍪

written by yunwon 2021. 11. 25. 11:50

 

 

 

프로젝트를 진행하며 오류를 파헤쳐본 결과,

안드로이드 상에서는 웹뷰가 크게 문제되는 부분이 없었다.

그래도 며칠간 조사한 부분이니까 쿠키 매니저에 관해 기록하고 싶어서

챱 챱 챱 🍪

 

주로 CookieManager 에 대해 다룰 것이며,

추가적으로 CutomTabIntents 와 WebView 간의 쿠키 공유에 대해서

(이 부분은 조금 더 조사가 필요하지만) 서술하고 마무리할 예정이다 !

본격적인 글 작성에 앞서 기본 개념부터 다루어 본다면,

 

세션 = 서버에서 가지고 있는 정보

쿠키 = 사용자에게 발급된 세션을 열기 위한 열쇠

 

 


 

Cookie

쿠키는 웹 사이트에 방문한 사용자의 디바이스에 저장해 놓은 작은 데이터 파일로,

주로 사용자가 사이트를 재방문했을 때 편리함을 제공하기 위해 데이터를 저장한다.

사이트별로 쿠키를 관리하며, 보안상의 이유로 개인 정보 등의 민감한 정보는 쿠키로 저장해두는 일을 지양한다.

 

간단하게 쿠키는 안드로이드의 SharedPreferences 와 같은 기능을 하는데, 쿠키는 웹 사이트에서 관리한다.

웹뷰를 띄워 앱을 동작시키는데 쿠키가 왜 필요한가 ? 에 대해서 의문을 많이 가졌는데

 

(1) Persistance 를 유지해주기 위해서 -> 앱이 종료되기 전까지는 쿠키가 유지됨을 확인했다.

(2) WebView 와의 Cookie Sync 를 위해서

 

이렇게 크게 두 가지 이유를 생각하면 될 것 같다.

그러한 쿠키를 다루기 위해 안드로이드에서는 CookieManager, CookieSyncManager API 를 제공한다.

 

/ CookieSyncManager

하지만 CookieSyncManager 는 api21 부터 deprecated 되었다. (공식)

최근 안드로이드에서 제공하는 WebView 들은 자동으로 동기화가 이뤄지기 때문에,

수동으로 동기화 처리를 해줄 필요가 없기 때문이다.

 

수동으로 동기화가 필요할 경우 CookieManager 클래스의 flush() 를 사용하면 된다.

 

 

 


 

CookieManager

 

 

 

RFC2019 규약에 따라 쿠키를 관리한다.

기존 CookieSyncManager 가 deprecated 됨에 따라, 동기화를 비롯해 전반적인 관리는 해당 API 로 진행된다.

 

(1) 웹뷰 세션 유지

private void setCookieAllow(CookieManager cookieManager, WebView webView) {
        try {
            cookieManager = CookieManager.getInstance(); // CookieManager 초기화
            cookieManager.setAcceptCookie(true);
            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
                cookieManager.setAcceptThirdPartyCookies(webView, true);
            }
        } catch (Exception e) { }
}

 

 

(2) 쿠키 저장ㆍ불러오기

// 파라미터 url 을 키 값으로, value 값을 쿠키로 저장
setCookie(String url, Stirng value)

// 파라미터의 url 키에 저장된 쿠키 값 불러오기
getCookie(String url)

 

 

(3) 쿠키 보존 (동기화)

쿠키 저장 시점을 알 수 없는 앱의 입장에서,

웹뷰 페이지 로드가 끝나는 시점이나 액티비티의 생명주기에 쿠키 동기화를 진행해주어야 한다.

override fun onPageFinished(view: WebView?, url: String?) {
       super.onPageFinished(view, url)
       CookieManager.getInstance().flush()
}

WebViewClient onPageFinished 는 웹뷰 로딩이 끝났을 때 호출된다.

하지만 페이지 로드가 끝나고 뜬 팝업에 '하루 동안 보지 않기' 기능이 있을 경우,

해당 기능을 체크하고 팝업 종료 -> 앱 종료를 하여도 팝업이 지속적으로 나타난다. (쿠키 손실 현상)

 

이를 대비해 액티비티 생명주기 중 onDestroy 에 CookieManager.getInstance().flush() 를 추가하면 된다.

 

 

(4) 웹뷰 URL 감지

쿠키 유지를 적용시켜주면서, 웹뷰 내 모든 URL 변경을 감지하고 싶었다.

이러한 부분은 WebViewClient 의 shouldOverrideUrlLoading 에서 처리해주면 된다.

아래는 WebViewClient 를 상속받아 만든 클래스 내에서 URL 탐지하는 부분에 대해 로그를 찍는 코드이다.

@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
        Log.d("쿠키", request.getUrl().toString() + " 로 이동되었습니다.");
        return super.shouldOverrideUrlLoading(view, request);
}

 

 

 


 

 

CustomTabsIntent ⇔ WebView 간 쿠키 공유

 

그리고 . . 실질적으로 구현하고 싶었던 부분이다.

프로젝트에서는 기존 웹뷰에서 새창으로 이동할 때 같은 웹뷰로 이동하는 것이 아니라,

CustomTabsIntent 라고 하는 크롬 최적화된 인텐트 툴로 이동하고 있었다.

이러한 상황에서 기존 웹뷰 내에 있는 로그인 세션ㆍ쿠키를 유지하면서 새 창에서도 동작되도록 하고 싶었다.

 

WebView 간에는 위에서 살펴본 것처럼 CookieManager 를 사용하면 되었지만,

여기서는 따로 지원하는 툴이 없었다. 이러한 부분을 해결하기 위한 강구한 대책 프로세스에 대해 . .

 

 

💚 첫번째 방법

CustomTabsIntent 가 실행될 때, Header 에 WebView 가 가지고 있던 Cookie 값 넣어주기

이 때 WebView 가 가지고 있던 Cookie 정보는 CookieManager 의 getCookie 를 이용해,

웹뷰가 마지막으로 보던 페이지 URL (shouldOverrideUrlLoading) 에 대한 쿠키를 가져온다.

 

https://developer.chrome.com/docs/android/custom-tabs/headers/

 

How to add extra HTTP Request Headers to Custom Tab Intents - Chrome Developers

Guide for adding HTTP CORS headers in Custom Tab Intents.

developer.chrome.com

 

 

💚 두번째 방법

Cookie의 경우 보안상의 위험 때문에 연결하려는 웹 사이트에도 따로 파일을 만들어

정상적인 접근인지 확인하는 절차를 거치게 하면 된다.

=> 크롬 업데이트 이후에는 CORS safe-listed request headers 적용된다고 함

* CORS = HTTP Header 에 추가적인 정보를 넣어 서버가 브라우저에게 자기 자신뿐만 아니라

     다른 origin 에서 요청한 정보도 허용할 수 있도록 알려주는 것

 

https://developer.chrome.com/docs/android/custom-tabs/headers/#adding-extra-headers

https://stackoverflow.com/questions/62682574/android-params-inside-bundle-using-extra-headers-through-customtabs-intent-ar

 

Android - Params inside bundle using EXTRA_HEADERS through CustomTabs intent, are not received/readed by Google Chrome after app

Google Chrome was upgraded in Play Store to 83.0.4103.106 version (https://chromereleases.googleblog.com/2020/06/stable-channel-update-for-desktop_15.html). In there, Google team did some enforceme...

stackoverflow.com

 

 

 

.

.

결과적으로 해당 부분은 굳 이 구현할 필요가 없었다는 것을 듣게 되면서 놓았다.

안드로이드보다도 iOS 에서 쿠키 차단 정책이 강하게 들어가고 있어서 그 부분에서 더 많은 시간을 소요했다.

위 방법에 대해서는 정확히 적용해보지 못해서 맞을지 확신은 어렵지만 ,,

어느 정도 해결의 갈피는 잡을 수 있을 거라고 생각한다.

 

 

 

 

© 참고

https://superwony.tistory.com/50 (Android / 쿠키 매니저 다루기)

https://dbcp.tistory.com/37 (Android / CookieManager 를 사용해야 하는 이유)

 

[Android] CookieManager를 사용해야하는 이유

출처 : http://blog.naver.com/PostView.nhn?blogId=free2824&logNo=60175591849 1. CookieManager를 사용해야하는 이유 Server와 통신하다보면 Cookie를 보관해야할 일이 있다. Cookie는 CookieManager를 사용해..

dbcp.tistory.com