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

Flask Web应用与REST API共用登录体系及AJAX请求方案问询

问题:Flask项目中Flask-Login与JWT复用实现AJAX认证

我要开发一个同时集成REST API和Web应用的Flask项目,包含以下受保护路由:

  • Web应用路由:
    • /notes:查看用户所有笔记
    • /notes/<note_id>:查看指定笔记
  • REST API路由:
    • /api/notes
    • /api/notes/<note_id>

计划用Flask-Login实现Web应用的注册登录,用Flask-JWT-Extended实现REST API的认证。现在需要从/notes/1页面发起AJAX请求到/api/notes,加载用户笔记,这时候需要用到JWT令牌。我的疑问是:是否每次都必须先调用/api/login获取令牌?能不能让Flask-Login复用REST API的JWT令牌,在用户访问/notes/1页面时把令牌存在浏览器里,供JS脚本发起AJAX请求调用受保护的API路由?


回答

完全不用每次调用/api/login拿令牌,你可以让Flask-Login和JWT配合复用用户的认证状态,具体实现思路如下:

1. 在Web登录流程中生成并传递JWT令牌

当用户通过Flask-Login完成Web端登录(调用login_user()之后),后端直接生成JWT访问令牌,然后把令牌传递给前端页面:

  • 方案一:嵌入到模板变量
    后端渲染/notes/<note_id>页面时,把生成的令牌作为模板变量传入:

    from flask_jwt_extended import create_access_token
    
    @app.route('/notes/<note_id>')
    @login_required
    def view_note(note_id):
        # 生成JWT令牌,用当前登录用户的ID作为标识
        jwt_token = create_access_token(identity=current_user.id)
        return render_template('note.html', note_id=note_id, jwt_token=jwt_token)
    

    然后在前端模板里把令牌赋值给JS变量:

    <script>
      // 直接从模板获取令牌
      const authToken = "{{ jwt_token }}";
    </script>
    
  • 方案二:存入非HttpOnly Cookie
    如果不想在模板里暴露令牌,也可以把令牌存入非HttpOnly的Cookie(因为JS需要读取):

    @app.route('/login', methods=['POST'])
    def login():
        # 验证用户信息逻辑...
        login_user(user)
        jwt_token = create_access_token(identity=user.id)
        # 设置Cookie,httponly=False允许JS读取
        response = redirect(url_for('view_note', note_id=1))
        response.set_cookie('jwt_token', jwt_token, httponly=False, secure=True)
        return response
    

    前端JS通过document.cookie读取令牌:

    function getCookie(name) {
      const value = `; ${document.cookie}`;
      const parts = value.split(`; ${name}=`);
      if (parts.length === 2) return parts.pop().split(';').shift();
    }
    const authToken = getCookie('jwt_token');
    

2. 前端AJAX请求携带令牌

拿到令牌后,发起AJAX请求时把令牌放到Authorization请求头里,格式为Bearer <令牌>,Flask-JWT-Extended会自动识别并验证:

fetch('/api/notes', {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${authToken}`
  }
})
.then(response => {
  if (!response.ok) throw new Error('请求失败');
  return response.json();
})
.then(notes => {
  // 渲染笔记数据到页面
  console.log('用户笔记:', notes);
})
.catch(err => console.error(err));

3. 关键注意事项

  • XSS风险防范:如果用非HttpOnly Cookie存令牌,要确保页面没有XSS漏洞,避免令牌被窃取;用模板嵌入的方式相对更安全,因为令牌只在当前页面渲染时生成,不会长期存在Cookie里。
  • 过期时间同步:设置JWT的过期时间要和Flask-Login的Session过期时间尽量同步,避免出现Web端还处于登录状态,但JWT已经失效的情况。
  • 用户标识一致:生成JWT时用的identity要和Flask-Login的用户标识一致(比如都用用户ID),这样API端验证令牌后能正确关联到对应的用户数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 21:45:31