You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter Web应用中安全存储JWT令牌?

Flutter Web 安全存储JWT令牌的最佳实践

首先明确:直接用dart:html操作localStorage存储JWT是不推荐的——因为localStorage是明文存储,且可被前端JS任意读取,一旦页面遭遇XSS攻击,令牌会被恶意脚本窃取,进而冒充用户身份。

以下是针对Flutter Web的安全存储方案,按优先级排序:

1. HttpOnly + Secure Cookie(优先推荐)

这是Web场景下最安全的JWT存储方式,核心是让后端而非前端管理令牌:

  • 后端在登录成功后,将JWT写入带有以下属性的Cookie:
    • HttpOnly:禁止前端JS读取Cookie,彻底规避XSS窃取风险
    • Secure:仅在HTTPS连接下传输Cookie,防止明文泄露
    • SameSite=Strict/Lax:防范CSRF攻击
  • Flutter Web发起API请求时,只需在请求配置中开启withCredentials(以http包为例):
    import 'package:http/http.dart' as http;
    
    final response = await http.get(
      Uri.parse('https://your-api.com/protected'),
      headers: {'Content-Type': 'application/json'},
      // 允许携带Cookie
      withCredentials: true,
    );
    
  • 适用场景:同域API或已配置跨域Cookie支持的场景。

2. 专用安全存储库(客户端侧加密存储)

如果必须由前端存储令牌,可使用针对Flutter Web优化的安全存储库,这类库会对存储内容加密,降低明文泄露风险:

  • 推荐使用flutter_secure_storage(已支持Web端),它在Web上基于IndexedDB实现加密存储:
    import 'package:flutter_secure_storage/flutter_secure_storage.dart';
    
    // 初始化存储实例
    final storage = const FlutterSecureStorage();
    
    // 存储JWT
    await storage.write(key: 'auth_jwt', value: receivedJwtToken);
    
    // 读取JWT
    String? jwtToken = await storage.read(key: 'auth_jwt');
    
    // 删除JWT(登出时)
    await storage.delete(key: 'auth_jwt');
    
  • 注意:这类存储仍无法完全抵御XSS攻击(恶意脚本可直接调用存储API读取),需配合内容安全策略(CSP)进一步降低风险。

3. 会话存储(SessionStorage)

仅适合短期会话场景:

  • sessionStorage的生命周期与标签页绑定,关闭标签页后自动清除,比localStorage的持久化存储风险稍低,但依然是明文存储,XSS风险依旧存在。
  • 代码示例(用dart:html):
    import 'dart:html';
    
    // 存储
    window.sessionStorage['jwt_token'] = receivedJwt;
    
    // 读取
    String? jwt = window.sessionStorage['jwt_token'];
    

额外防护措施

无论采用哪种存储方式,都需搭配以下防护手段:

  • 启用内容安全策略(CSP):通过HTTP响应头设置Content-Security-Policy,限制脚本、样式等资源的加载来源,减少XSS攻击面,例如:script-src 'self'; style-src 'self'
  • 使用短生命周期JWT:设置较短的JWT过期时间(如15分钟),配合刷新令牌(Refresh Token)实现无感续期,刷新令牌需存储在HttpOnly Cookie中
  • 严格验证JWT:后端必须验证JWT的签名(优先使用非对称加密算法如RS256)、过期时间、受众(Audience)等字段,拒绝无效令牌
  • 禁止URL传递JWT:避免将JWT放在URL参数中,防止被服务器日志、浏览器历史或Referrer头泄露

内容的提问来源于stack exchange,提问作者18Ashelar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 20:22:45