首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android HttpURLConnection 登錄後 WebView Cookie 同步方案

     編輯:程式設計綜合問答

場景

App 用 HttpURLConnection POST 登錄,獲取 Cookie,需注入嵌入 WebView 實現免登訪問受保護頁面。

核心解決方案:CookieManager 同步


// 1. 登錄成功後,從 HttpURLConnection 獲取 Cookie
String cookieHeader = connection.getHeaderField("Set-Cookie"); // 可能多個,需解析合併
// 例: "SESSION=abc123; Path=/; HttpOnly, USER_ID=456; Path=/"

// 2. 同步到 WebView 的 CookieManager
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true); // 確保接受 Cookie

// 3. 逐條設置 (需解析域、路徑、屬性)
String url = "https://api.example.com"; // 目標域名
// 簡單粗暴:直接設置完整 Cookie 字串 (API 21+ 支援)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    CookieManager.getInstance().setCookie(url, cookieHeader);
} else {
    // 舊版需手動解析 name=value; domain=...; path=...
    // 建議用開源庫: cookie-manager 或自行解析
}

// 4. 強制刷新持久化 (API 21+)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    CookieManager.getInstance().flush();
}

完整登錄 + WebView 載入流程


public class LoginActivity extends AppCompatActivity {
    private WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        webView = findViewById(R.id.webview);
        WebSettings settings = webView.getSettings();
        settings.setJavaScriptEnabled(true);
        // 關鍵:允許第三方 Cookie (API 21+)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            CookieManager.getInstance().setAcceptThirdPartyCookies(webView, true);
        }

        // 異步登錄
        new LoginTask().execute("user", "pass");
    }

    private class LoginTask extends AsyncTask {
        @Override
        protected String doInBackground(String... params) {
            try {
                URL url = new URL("https://api.example.com/login");
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("POST");
                conn.setDoOutput(true);
                // 寫入表單數據...
                
                // 獲取 Cookie
                String cookie = conn.getHeaderField("Set-Cookie");
                return cookie;
            } catch (IOException e) {
                return null;
            }
        }

        @Override
        protected void onPostExecute(String cookie) {
            if (cookie != null) {
                // 同步 Cookie
                String domain = "https://api.example.com";
                CookieManager.getInstance().setCookie(domain, cookie);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    CookieManager.getInstance().flush();
                }
                // 載入受保護頁面
                webView.loadUrl("https://api.example.com/protected/page");
            } else {
                Toast.makeText(LoginActivity.this, "登錄失敗", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

進階:持久化 Cookie 避免重複登錄


// 登錄成功後保存到 SharedPreferences
SharedPreferences prefs = getSharedPreferences("auth", MODE_PRIVATE);
prefs.edit().putString("cookie", cookie).apply();

// App 啟動時恢復
String savedCookie = prefs.getString("cookie", null);
if (savedCookie != null) {
    CookieManager.getInstance().setCookie(domain, savedCookie);
    CookieManager.getInstance().flush();
}

常見坑點

問題原因解決
WebView 仍提示未登錄Cookie 域/路徑不匹配、HttpOnly 無法讀取確保 setCookie 域名與 WebView 載入 URL 域名一致
API < 21 setCookie 失效舊版不支援完整 Cookie 字串解析手動解析 name=value; domain=...; path=... 逐條 setCookie
第三方 Cookie 被瀏覽器阻擋Android 5.0+ 默認阻擋第三方 CookiesetAcceptThirdPartyCookies(webView, true)
重定向丟失 CookieHttpURLConnection 默認不自動處理重定向 Cookieconn.setInstanceFollowRedirects(false) 手動處理重定向並合併 Cookie

現代替代:OkHttp + WebView

OkHttp 自動管理 CookieJar,攔截器中同步到 CookieManager 更優雅:


OkHttpClient client = new OkHttpClient.Builder()
    .cookieJar(new CookieJar() {
        private final HashMap> store = new HashMap<>();
        @Override public void saveFromResponse(HttpUrl url, List cookies) {
            store.put(url, cookies);
            syncToWebView(url, cookies); // 同步到 WebView
        }
        @Override public List loadForRequest(HttpUrl url) {
            return store.getOrDefault(url, Collections.emptyList());
        }
    })
    .build();
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved