[Andorid] WebViewでSNSログインが失敗する原因まとめ

スポンサーリンク
  1. 導入:ブラウザではログインできるのに、WebViewだと失敗する
  2. 前提:SNSログインは「WebView前提じゃない」ことが多い
  3. 切り分けの最短ルート:まず「失敗のタイプ」を決める
    1. タイプA:ログイン後に元の画面に戻れない(真っ白/無限ループ)
    2. タイプB:ログイン画面が最初から弾かれる(非対応ブラウザ/セキュリティ警告)
    3. タイプC:途中まで進むが、認可画面や同意画面で失敗する
  4. 原因1:Cookie(9割ここ)
    1. 1-1. サードパーティCookieがブロックされている
      1. チェック:サードパーティCookieを許可しているか
    2. 1-2. SameSite の影響でCookieが送られない
    3. 1-3. Cookieが「保存されていない」または「突然消える」
      1. チェックポイント
      2. Cookieを明示的にflushする(必要な場面のみ)
    4. 1-4. カスタムタブ/外部ブラウザとCookieが共有されない
  5. 原因2:User-Agent(UA)で弾かれる
    1. 2-1. WebView判定で「サポート外」になる
    2. 2-2. UAをカスタムして壊している
      1. 正しいUAカスタムの基本:末尾に追加
    3. 2-3. UA変更のタイミングが遅い
  6. 原因3:リダイレクト(shouldOverrideUrlLoading/intent/フラグメント)
    1. 3-1. shouldOverrideUrlLoading で握りつぶしている
      1. 基本方針
      2. 例:アプリに戻るURLだけ拾う
    2. 3-2. フラグメント(#)以降に重要情報がある
    3. 3-3. intent:// や market:// が混ざる
  7. 追加で疑うべき原因(実務で多い)
    1. 4) TLS/SSLハンドシェイク失敗
    2. 5) WebViewのデバッグ不足(何が起きているか見えてない)
  8. 最短で直すための「切り分け手順」
  9. デバッグ/確認チェックリスト
  10. よくある質問(Q&A)
    1. Q. どうしてもWebViewでSNSログインしたい
    2. Q. Cookieを全部許可すれば解決する?
    3. Q. UAをChromeっぽく偽装すれば通る?
  11. まとめ:原因はだいたいCookie/UA/リダイレクト

導入:ブラウザではログインできるのに、WebViewだと失敗する

SNSログイン(Google / X / Facebook / LINE など)をアプリ内でやりたい。
で、WebViewでログイン画面を開く。

……すると、こうなります。

  • ブラウザでは成功するのにWebViewだと弾かれる
  • ログイン後に真っ白、または無限リダイレクト
  • 「このブラウザはサポートされていません」的な表示
  • 途中でCookieが消えて最初に戻る

これ、WebViewでSNSログインをやる限り、かなりの確率で踏みます。

結論から言うと、原因はだいたい Cookie / UA / リダイレクト のどれか、もしくは複合です。

この記事では、WebViewでSNSログインが失敗する原因を「切り分け順」でまとめます。
闇雲に設定を盛ると余計壊れるので、順番が大事です。

先に結論(3行)です。

  • まずCookie(特にサードパーティCookieとSameSite)を疑う
  • 次にUA(アプリ内ブラウザ判定で弾かれる系)を疑う
  • 最後にリダイレクト(shouldOverrideUrlLoading/フラグメント/intent起動)を疑う

前提:SNSログインは「WebView前提じゃない」ことが多い

まず厳しめの現実から。
SNSログインは、多くの場合「ブラウザ(システムブラウザ)での実行」を前提に作られています。

WebViewは自由度が高い反面、セキュリティ制約やCookie制約が強く、提供側が明示的に非サポートにしているケースもあります。

つまり、WebViewで通らない時に「アプリ側で何とかすれば必ず通る」とは限りません。
それでも、実務ではどうしてもWebViewでやらざるを得ないケースがあるので、現実的な対策を詰めていきます。

切り分けの最短ルート:まず「失敗のタイプ」を決める

原因特定のスピードが上がるので、最初に症状を分類します。

タイプA:ログイン後に元の画面に戻れない(真っ白/無限ループ)

リダイレクト処理かCookieが濃厚です。

タイプB:ログイン画面が最初から弾かれる(非対応ブラウザ/セキュリティ警告)

UAやWebView判定(アプリ内ブラウザ拒否)が濃厚です。

タイプC:途中まで進むが、認可画面や同意画面で失敗する

Cookie(SameSiteやサードパーティ)か、リダイレクト途中のintent処理が濃厚です。

原因1:Cookie(9割ここ)

WebViewでSNSログインが失敗する最大原因はCookieです。

1-1. サードパーティCookieがブロックされている

SNSログインはドメインをまたいだ遷移が多く、サードパーティCookieが絡みやすいです。
WebView側でサードパーティCookieが無効だと、認証セッションが維持できずに詰みます。

チェック:サードパーティCookieを許可しているか

val cm = CookieManager.getInstance()
cm.setAcceptCookie(true)
cm.setAcceptThirdPartyCookies(webView, true)

ただし、何でも許可すれば良いわけではありません。
許可するなら「ログイン画面で必要な範囲に限定」し、ログイン後に戻すなど、運用設計が必要です。

1-2. SameSite の影響でCookieが送られない

最近はSameSite制約が強く、クロスサイト遷移でCookieが送られないケースがあります。
ブラウザではうまくいくのにWebViewではダメ、が起きる代表例です。

この場合、アプリ側で出来ることは限られます。
Web側(認証側)がSameSite=None; Secure を適切に設定していないと、根本的に詰む可能性があります。

1-3. Cookieが「保存されていない」または「突然消える」

WebViewのプロセスが落ちたり、アプリ側でCookieをクリアしたりすると、途中でセッションが消えます。

チェックポイント

  • ログイン開始前に CookieManager.removeAllCookies を呼んでいないか
  • WebViewを画面回転で作り直していないか
  • プロセスキル後の復元でWebViewが再生成されていないか

Cookieを明示的にflushする(必要な場面のみ)

CookieManager.getInstance().flush()

「ログイン直後に戻りURLへ飛ぶ直前」など、タイミングが重要な場面で効くことがあります。
ただし多用は避けます。

1-4. カスタムタブ/外部ブラウザとCookieが共有されない

WebViewとChrome(Custom Tabs含む)はCookieジャーが別の場合があります。
「外部ブラウザでログイン済みなのにWebViewだけ未ログイン」は、ここが原因のことが多いです。

これをアプリ側で完全に合わせるのは難しく、設計として「ログインはWebViewではなくCustom Tabsに寄せる」方が現実的な場合もあります。

原因2:User-Agent(UA)で弾かれる

SNSログインは「この環境は安全か」を見ています。
WebViewはUAや環境情報で「アプリ内ブラウザ」と判定され、弾かれることがあります。

2-1. WebView判定で「サポート外」になる

典型は「このブラウザはサポートされていません」系です。
Web側がWebViewを拒否している可能性があります。

2-2. UAをカスタムして壊している

UAを上書きしていると、予期せぬ判定に引っかかります。
特に「デフォルトUAを捨てて独自UAだけにする」は危険です。

正しいUAカスタムの基本:末尾に追加

val defaultUa = webView.settings.userAgentString
webView.settings.userAgentString = "$defaultUa MyApp/${BuildConfig.VERSION_NAME}"

デフォルトUAを残すと、ブラウザ判定が壊れにくいです。

2-3. UA変更のタイミングが遅い

UAは loadUrl の前に設定しないと、最初のリクエストに反映されません。
ログインで最初のリクエストが重要なので、ここで詰みます。

原因3:リダイレクト(shouldOverrideUrlLoading/intent/フラグメント)

ログインが通っているのに「戻れない」「真っ白」は、だいたいリダイレクト処理が壊れています。

3-1. shouldOverrideUrlLoading で握りつぶしている

ありがちなのが、全URLを自前で処理しようとして false/true の返し方を間違えるパターンです。

基本方針

  • WebViewに表示させたい遷移は WebView に任せる(基本 false)
  • アプリで処理したいURLだけ拾う(特定スキームや特定host)

例:アプリに戻るURLだけ拾う

webView.webViewClient = object : WebViewClient() {
    override fun shouldOverrideUrlLoading(
        view: WebView,
        request: WebResourceRequest
    ): Boolean {
        val url = request.url.toString()

        // 例:myapp://callback を拾う
        if (url.startsWith("myapp://callback")) {
            // アプリ側で処理
            handleCallback(url)
            return true // WebViewには任せない
        }
        return false // WebViewに任せる
    }
}

3-2. フラグメント(#)以降に重要情報がある

OAuth系は、#(フラグメント)にトークンや情報が乗る場合があります。
HTTPリクエストではサーバに送られないので、アプリ側でURLを正しく扱わないと情報が取れません。

WebViewでフラグメントが消える/変なエンコードになると、ログイン後の処理が破綻します。

3-3. intent:// や market:// が混ざる

ログイン途中で別アプリ起動(認証アプリ、パスワードマネージャなど)が挟まる場合があります。
WebViewでこれを処理できずに詰むことがあります。

この場合は、intentスキームを検知して外部に逃がす設計が必要です。

追加で疑うべき原因(実務で多い)

4) TLS/SSLハンドシェイク失敗

特定端末や古いWebViewでTLSが合わず、ログイン先に到達できないケースがあります。
Logcatに SSLHandshakeException が出ているならここです。

5) WebViewのデバッグ不足(何が起きているか見えてない)

WebViewはログが見えづらいので、通信・Cookie・リダイレクトを可視化した方が早いです。

  • Chrome DevTools(WebViewのリモートデバッグ)
  • Proxyツールで通信を見る(HTTPS復号)
  • User-Agent、Cookieの差分を記録する

最短で直すための「切り分け手順」

  1. ブラウザでは成功するか(Web側の問題切り分け)
  2. WebViewのCookie許可(特にサードパーティ)を確認
  3. UAをデフォルト+末尾追加に戻す
  4. shouldOverrideUrlLoading を「拾うURLだけ拾う」に修正
  5. フラグメント/intentスキームが混ざっていないか確認

この順番でやると、最短で原因に刺さりやすいです。

デバッグ/確認チェックリスト

  • サードパーティCookieを必要な範囲で許可している
  • Cookieが途中で消えていない(clear/再生成/プロセスキル)
  • UAはデフォルトを残して末尾追加
  • UA設定はloadUrl前
  • shouldOverrideUrlLoadingは特定URLだけ拾う
  • フラグメントやintentスキームの扱いを確認
  • 通信可視化(DevTools/Proxy)を使っている

よくある質問(Q&A)

Q. どうしてもWebViewでSNSログインしたい

可能なこともありますが、提供側が非サポートの場合は詰む可能性があります。
その場合は、ログインだけCustom Tabsに寄せる設計を検討した方が安全です。

Q. Cookieを全部許可すれば解決する?

一時的に通ることはありますが、セキュリティと整合性のリスクが上がります。
必要な範囲で許可し、ログイン後に戻す、など運用設計が必要です。

Q. UAをChromeっぽく偽装すれば通る?

通ることもありますが、提供側の規約や仕様に触れる可能性があります。
まずは「デフォルトUAを壊していないか」を疑うのが安全です。

まとめ:原因はだいたいCookie/UA/リダイレクト

  • WebViewログイン失敗の最大原因はCookie(サードパーティ/SameSite)
  • 次にUA(WebView拒否/カスタムで壊す)
  • 最後にリダイレクト処理(shouldOverrideUrlLoading/intent/フラグメント)

迷ったら:Cookieを見て、UAを戻して、拾うURLだけ拾う。
この3点で、だいたい前に進みます。

コメント

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