Open hushicai opened 5 years ago
let storage = require('./storage'); 请问大神这里的storage 是 AsyncStorage吗,storage.getCookie()中这个getCooKie()方法从哪里来的?是自己定义的还是AsyncStorage的? 求解答
let storage = require('./storage'); 请问大神这里的storage 是 AsyncStorage吗,storage.getCookie()中这个getCooKie()方法从哪里来的?是自己定义的还是AsyncStorage的? 求解答
嗯,就是AsyncStorage,一个简单的key/value存储就可以了。核心就是手动在所有请求的headers带上之前的cookie。
最近我们遇上了一些比较棘手的问题:
这篇文章尝试解释以上问题以及我们如何解决它。
问题:不靠谱的cookie存储
经过一番调试定位后,我们发现,当app重新打开时,app有时候会向服务器发送无效cookie,所以导致了上述问题。
我们一直无法找出为什么无效cookie会被发送的原因,直到我们碰上了这个核心问题:由底层原生框架提供给React Native的cookie存储并非100%可靠。
React Native的fetch是在原生网络技术栈上实现的。
Cookies是由这些原生技术栈管理的,而不是React Native本身[Github][StackOverflow]。
(React Native takes advantage of native functionality on iOS and Android)
我们发现有两个可能引起上述bug的原因:
可能原因1:原生API存储了错误的cookie
我们查看了一下Apple和Google给它们的原生网络技术栈定义的cookie接收文档:
IOS(NSURLConnection):
Android(CookieManager):
既然React Native是在这些APIs的基础上实现的,那么在应用层级上手动设置的cookie就有可能会被原生API修改,并且被替换成原生的cookie(IOS cookies,Android CookieStore)。
因为cookie是透明处理的,所以如果要进一步调试这个设想,需要编写原生代码,我们决定现在先避免它。
可能原因2:Cookies没有被恰当地持久化
默认地,为了性能原因,cookies首先存储在RAM中,然后定时地同步到永久存储中(Android CookieSyncManager,IOS NSHTTPCookieStorage)。
在iOS [StackOverflow]和Android [StackOverflow]上,cookie都可能永远不会最终成为持久存储(例如应用程序在打开后很快关闭)。
StackOverflow上建议,对于Android,强制cookie重新同步;对于iOS,扩展原生API以手动管理cookie。
我们仍然不确定可能导致cookie持久化失败的特定条件,但此时看起来构建一个变通方法可能比在原生层面上修复更快。
解决方案:手动管理cookie
既然我们无法依靠默认功能来实现可靠的cookie存储,因此我们决定自己动手处理并自行管理会话cookie。
我们选择使用
AsyncStorage
来存储我们的cookie,并在每个请求的http头部中设置该cookie。 这样,即使应用程序已关闭或更新,我们也可以确保持久存储正确的cookie。 我们还使用了名为react-native-cookies的第三方库,在每个请求之前,刷新原生cookie管理器存储的cookie,以便与请求一起发送正确的cookie(我们自己从AsyncStorage中检索到的cookie)。以下是我们的代码片段,用于演示此过程的工作原理:
这样修改之后,我们解决了上面的问题,我们的用户现在可以很愉快地在我们的app中保持登录态。 如果你也遇到了同样的问题,我们希望这篇文章可以帮到你。
安全性
如果你觉得
AsyncStorage
不够安全,你可以参考react-native-sensitive-info的keystore分支,它基于IOS Keychain和Android keyStore提供了加密的本地存储。参考文章
https://build.affinity.co/persisting-sessions-with-react-native-4c46af3bfd83