如何在Flask后端向ReactJS前端设置Cookie 跨域Cookie不生效问题求解
问题根因&修复方案
核心错误点
你当前代码的最大问题是构造了带Cookie的响应对象后没有实际返回它,最后返回的jsonify({'response': response.json})是一个全新的响应实例,之前设置的Cookie、响应头全部丢失,自然浏览器收不到Set-Cookie指令。
后端Flask代码修改
需调整的配置项
set_cookie的domain参数不能携带端口,Cookie的域名规则不识别端口号,同IP不同端口会共享Cookie- 本地HTTP开发环境下需显式设置
secure=False(secure=True仅在HTTPS环境下生效),补充samesite配置避免浏览器拦截 @cross_origin装饰器需显式开启supports_credentials=True- 直接返回构造好的带Cookie的响应对象,不要重新生成JSON响应
修改后代码示例
# login route - this will set cookie (JWT token) @app.route('/login', methods=['POST']) @cross_origin(supports_credentials=True) def login(): auth = request.authorization # the auth should have a username and a password user = User.query.filter_by(username=auth['username']).first() if not user: return jsonify({'msg': 'user not found'}), 404 if bcrypt.check_password_hash(user.password, auth['password']): # generate a token access_token = create_access_token(identity=user.username, expires_delta=datetime.timedelta(days=1)) response = make_response(jsonify({'msg': 'successfully logged in!'}), 200) # 不需要显式加Access-Control-Allow-Credentials头,cross_origin装饰器会自动处理 response.set_cookie( 'access_token', value=access_token, # 本地开发可以省略domain参数,默认会匹配请求的源IP # 如需填写请不要带端口:domain='127.0.0.1' samesite='Lax', secure=False # 生产环境HTTPS下改为True ) # 直接返回带Cookie的response对象,不要重新jsonify return response return jsonify({'msg': 'wrong credentials'}), 401
前端React请求配置
跨域请求要携带/接收Cookie,必须显式开启凭据配置:
- 如果你使用
axios发请求:axios.post('http://127.0.0.1:5000/login', { // 你的请求参数 }, { withCredentials: true }) - 如果你使用原生
fetch发请求:fetch('http://127.0.0.1:5000/login', { method: 'POST', credentials: 'include', // 其他请求配置 })
额外注意事项
- 前后端访问地址要统一使用
127.0.0.1或者统一使用localhost,不要混用,二者在Cookie规则中会被识别为不同的域 - 排查时可以打开浏览器控制台的「网络」面板,查看login请求的响应头是否存在
Set-Cookie字段,如果有灰色感叹号可以悬停查看具体拦截原因
内容的提问来源于stack exchange,提问作者ismail pervez
相关产品推荐
相关产品推荐

