[Android]WebViewでCookieを正しく扱うテクニックまとめ

今回の記事では、以前紹介したWebViewのCookieの処理から一歩踏み込んで、実際のプロダクトで必要になるCookie運用テクニックをまとめます。

特に最近のChromeのCookie仕様(SameSite強化)やWebViewの挙動変化により、
「Cookieを入れているのに認証されない…」
「外部ブラウザとのCookie共有ができない…」
といったハマりポイントが非常に増えています。

この記事では、そんな実務トラブルを避けるために、Android WebView × Cookie の応用的な扱い方をわかりやすくまとめます。


1. WebViewでCookieを有効化する(基本設定)

まずはいつものWebView初期設定。
ただし、サードパーティCookieの許可は必ず明示する必要があります。


val cookieManager = CookieManager.getInstance().apply {
    setAcceptCookie(true)
    setAcceptThirdPartyCookies(webView, true)
}

webView.settings.apply {
    javaScriptEnabled = true
    domStorageEnabled = true
    mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
}

最近のサービスでは外部リソースの埋め込みが多く、
setAcceptThirdPartyCookies を忘れるとログインが通らないことがあるので注意です。


2. ネイティブ側でCookieをセットする(ログイン前に付与)

実務でよくあるのが、アプリ起動時にネイティブが認証トークンを保持しているパターン
この場合はWebView読込前にCookieを注入しておく必要があります。


fun setLoginCookie(token: String) {
    val url = "https://example.com/"
    val cookie = "auth_token=$token; Path=/; Secure; HttpOnly; SameSite=None"

    val cookieManager = CookieManager.getInstance()
    cookieManager.setCookie(url, cookie)

    // 非同期 → 同期へ確実に反映
    CookieManager.getInstance().flush()
}

SameSite=None; Secure を付けないとChrome系のWebViewで弾かれるため、
APIと相談のうえ必ず指定しましょう。


3. 特定ドメインだけCookieを付与する(複数ドメイン対応)

最近のWebアプリでは、API・静的コンテンツ・認証などが別ドメイン化していることがよくあります。

例:

  • WebView表示:https://app.example.com
  • 認証:https://auth.example.com
  • API:https://api.example.com

この場合、目的のドメインごとにCookieを正しく付ける必要があります。


fun setMultiDomainCookie(token: String) {
    val domains = listOf(
        "https://app.example.com",
        "https://auth.example.com",
        "https://api.example.com"
    )

    val cookieValue = "auth=$token; Path=/; Secure; SameSite=None"

    val cm = CookieManager.getInstance()
    domains.forEach { domain ->
        cm.setCookie(domain, cookieValue)
    }
    cm.flush()
}

WebViewはトップレベルドメインのCookieを勝手に配布してくれないため、
手動で全ドメインへ配布するのが実務的な対応です。


4. Cookieをログで確認する(デバッグ用)

Cookieに問題があるとき、まずはネイティブ・WebView・JSのどこで消えているかを確認する必要があります。

デバッグではログ確認が最強です👇


fun logCookie(url: String) {
    val cookies = CookieManager.getInstance().getCookie(url)
    Log.d("CookieCheck", "[$url] → $cookies")
}

これで「ネイティブから消えているのか」「WebView移動時に消えているのか」が判断できます。


5. 外部ブラウザ(Chromeなど)とCookieを共有する方法

残念ながら、ネイティブ → Chrome のCookieはOS標準では共有されません

ただし実務では以下のワークフローで実現できます:

  • WebViewでログイン状態を作る
  • URLを Chrome Custom Tabs で開く
  • サーバー側で SameSite=None; Secure のCookieを配布

つまり、サーバー側がユーザー識別Cookieを発行すればChrome側でもログイン済になるということです。

アプリからは以下のように遷移:


val customTabs = CustomTabsIntent.Builder().build()
customTabs.launchUrl(context, Uri.parse("https://app.example.com/mypage"))

ChromeとWebView間で完全共有は不可ですが、
サーバー側でのCookie発行を経由することで「実質ログイン状態の同期」ができます。


6. JavaScript から Cookie を操作する(双方向連携)

WebView × Cookie の仕上げとして、
JavaScript → ネイティブ → 再セット の流れを作ると強力です。

例:JS側で新しいトークンを取得したらネイティブに通知する


// ネイティブ側
class JsBridge {

    @JavascriptInterface
    fun onReceiveToken(token: String) {
        setLoginCookie(token)
    }
}

WebViewへの登録:


webView.addJavascriptInterface(JsBridge(), "Android")

Web側:


Android.onReceiveToken("newToken_12345");

これでWeb側でトークン更新 → アプリ側も即時更新ができます。


まとめ

今回紹介した技術を使えば、WebView上の認証系トラブルはかなり減らせます:

  • 複数ドメインに対してCookieを正しく付与
  • SameSite=None; Secure を必ず付ける
  • ネイティブ→WebView のログイン同期
  • JS→ネイティブ のトークン更新連携
  • ChromeとのCookie共有はサーバー側が鍵

WebView周りは細かい仕様に左右されがちですが、
ポイントさえ押さえれば非常に安定した挙動になります。

コメント

タイトルとURLをコピーしました