項目中使用了持久化登陸,即首次登陸后將 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();
}
}
真是無力吐槽,心力交瘁……
完。