React-Native SecureStore仅支持移动端,Web端如何安全存储JWT
问题说明
SecureStore 无法在Web端运行,原有跨端兼容实现代码如下:
async function getUserDetails() { try { // 原生Android/iOS端逻辑 const token = await SecureStore.getItemAsync('token') const data = await axios.get(apiurl+'&JWT='+token) console.log('using SecureStore') } catch (err) { // Web端降级逻辑 const token = await AsyncStorage.getItem('token') const data = await axios.get(apiurl+'&JWT='+token) console.log('using AsyncStorage') } }
该实现下浏览器环境会将JWT明文存储在AsyncStorage(Web端本质封装的是localStorage),可被任意页面JS读取,一旦站点存在XSS漏洞,攻击者可以直接窃取令牌冒用用户身份,可按以下方案修复:
可行修复方案
- 优先替换Web端JWT存储方案:
最稳妥的方案是将JWT存在设置了
HttpOnly、Secure、SameSite=Strict属性的Cookie中。这类Cookie完全禁止前端JS通过document.cookie读取,只会在浏览器向同域服务端发起请求时自动携带,从根源上避免XSS窃取令牌的问题。如果接口是跨域部署,需要配套配置CORS跨域策略,axios请求侧开启withCredentials: true允许携带凭证。
如果受现有架构限制必须由前端JS持有令牌,不要用持久化的localStorage/AsyncStorage存,改用内存变量存储(比如全局状态、闭包内变量),令牌只在当前页面会话周期内有效,页面刷新/关闭后就清除,重新走授权流程,大幅压缩令牌泄露后的可利用窗口。 - 修正分支判断逻辑:不要靠捕获SecureStore调用异常来区分端环境,提前用跨端框架提供的环境判断API(比如Platform.OS、Taro.getEnv())明确区分原生端、Web端的执行分支,避免移动端偶发SecureStore调用异常时,意外落到Web端明文存储的逻辑里。
- 补全Web端基础安全防护:即使调整了存储逻辑,也要配置严格的CSP内容安全策略,对所有用户输入、渲染内容做XSS转义,严格审核第三方引入的前端资源,从入口阻断XSS攻击的可能。
- 缩短JWT有效期:给访问用的JWT设置15分钟以内的短有效期,搭配单独的刷新令牌机制做无感续期,就算出现极端情况令牌泄露,攻击者可冒用身份的时间窗口也非常有限。
内容的提问来源于stack exchange,提问作者Rollor
相关产品推荐
相关产品推荐

