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
相关产品推荐
相关产品推荐

