Android 下 Cookie 保存機制的問題

項目中使用了持久化登陸,即首次登陸后將 Cookie 保存到本地,下次進入應(yīng)用時可以免登陸操作(此項由 React Naitve 幫助我們完成,只要服務(wù)器設(shè)置了 Set-Cookie 響應(yīng)頭即可,Cookie 失效的時間由服務(wù)器確定)。
應(yīng)用的邏輯是這樣的:首次使用應(yīng)用時需要登陸,登陸成功后后端在本地種植 Cookie,下次開啟應(yīng)用時無需再進行登陸,每次請求接口時都會帶上 Cookie,后端校驗如果 Cookie 失效會將請求重定向至 AuthFailed,一旦請求重定向至 AuthFailed,就需要跳轉(zhuǎn)到登錄界面重新登陸。
一直以來,這項功能都穩(wěn)定和諧的運行著,直到有一天我突發(fā)奇想:如果在登陸后立馬退出應(yīng)用,會是一種怎樣的體驗?zāi)??從此走向了一條不歸路……
我發(fā)現(xiàn)在登陸后立馬退出應(yīng)用,下次再進入應(yīng)用時仍然會跳轉(zhuǎn)到登陸頁面(我們在應(yīng)用功能啟動時會有一個驗證操作,校驗 Cookie 是否有效,如果失效就會跳轉(zhuǎn)到登錄頁面),這令人百思不得其解。
其實一開始我并沒有意識到這是 Android 下 Cookie 保存機制的問題,因為在那之前我增加了新的功能,自然而然想到是新功能引起的 bug,但我一直找不到 bug
是由什么引起的,后來當我一個 Commit 一個 Commit 進行回退驗證,直至回退到上一個穩(wěn)定版本,還是出現(xiàn)了這個問題。
我開始懷疑是后端接口的問題,于是開始抓包分析,發(fā)現(xiàn)有時候請求頭中并沒有帶上 Cookie,而 IOS 下又沒有此問題,我就想是不是安卓下無法正常的保存 Cookie,按照這個思路,我做了以下嘗試:

  • 使用 react-native-cookies 在登陸成功后手動設(shè)置 Cookie
  • 設(shè)置 fetch 請求頭的 credentials 項為 include 或者 same-origin

此外,還進行大量的搜索,查看 Issue 等,結(jié)果都是失敗。
后面偶然間發(fā)現(xiàn)了一篇文章,說道這可能是 Android 下 Cookie 保存機制的問題:

Synchronize the browser cookie store between RAM and permanent storage.
To get the best performance, browser cookies are saved in RAM.
A separate thread saves the cookies between, driven by a timer.

The sync interval is 5 minutes, so you will want to force syncs manually anyway.

文章鏈接在此
也就是說,當我登陸成功后立馬退出應(yīng)用,Android 端可能還來不及保存 Cookie,造成下一次登錄時持久化失效。按照文章中的解決方案修改了 MainActivity.java 文件,再次執(zhí)行前面的變態(tài)操作,也就可以了。以下是新增的配置代碼(增加了原文中沒有導(dǎo)入的兩個包):

// Handle Cookies
import android.webkit.CookieSyncManager;
import android.os.Build;
import android.webkit.CookieManager;

public class MainActivity extends ReactActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initCookie();
    }

    @Override
    protected void onStop() {
        saveCookie();
        super.onStop();
    }

    private void initCookie() {
        if (Build.VERSION.SDK_INT < 21) CookieSyncManager.createInstance(this);
    }
    private void saveCookie() {
        if (Build.VERSION.SDK_INT >= 21) CookieManager.getInstance().flush();
        else CookieSyncManager.getInstance().sync();
    }
}

真是無力吐槽,心力交瘁……

完。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容