【问题标题】:CORS fails to work once I add a JWT authorization header添加 JWT 授权标头后,CORS 无法工作
【发布时间】:2020-01-09 04:02:37
【问题描述】:

我有一个 Flask 后端和一个 React 前端。 Flask 后端是一个与其他微服务通信的 API。在开发中,我的 React 前端在 localhost:3000 上运行,Flask 应用程序在 localhost:5000 上运行。 显然,这些是不同的端口,默认情况下会引发 CORS 错误。所以我添加了 Flask_CORS 并允许来自 localhost:3000 的流量。这可行,我现在可以处理 GET 和 POST 请求。

然后我将我的 Firebase 身份验证添加到前端。我收到一个 JWT,然后我想发送带有 ech API 请求的 JWT,以确保允许用户发出某些请求,这些请求将在 Flask 后端进行验证。

我将 token_id 添加到后端的 Axios 请求的标头中,但现在我收到以下错误:

localhost/:1 从源 'http://localhost:3000' 访问 XMLHttpRequest 在 'http://localhost:5000/items' 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:否 'Access-Control-Allow-请求的资源上存在 Origin' 标头。

当我检查网络选项卡时,我注意到没有 JWT 请求可以正常通过。标题内容见下文:

  • 一般:

    • 请求网址:http://localhost:5000/items
    • 请求方法:GET
    • 状态码:200 OK
    • 远程地址:127.0.0.1:5000
    • 推荐人政策:降级时无推荐人
  • 响应标头:

    • Access-Control-Allow-Origin: http://localhost:3000
    • 内容长度:37
    • 内容类型:应用程序/json
    • 日期:格林威治标准时间 2019 年 9 月 6 日星期五 09:10:10
    • 服务器:Werkzeug/0.15.5 Python/3.7.4
    • 变化:原产地
  • 请求标头:

    • 显示临时标题
    • 接受:应用程序/json、文本/纯文本、/
    • 来源:http://localhost:3000
    • 推荐人:http://localhost:3000/
    • Sec-Fetch-Mode:cors
    • 用户代理:Mozilla/5.0(Windows NT 10.0;Win64;x64)AppleWebKit/537.36(KHTML,如 Gecko)Chrome/76.0.3809.132 Safari/537.36

然后我只将 JWT 添加到 Axios 拦截器的授权标头配置中,现在请求失败,网络选项卡中出现以下标头:

  • 一般:
    • 请求网址:http://localhost:5000/items
    • 请求方法:选项
    • 状态码:200 OK
    • 远程地址:127.0.0.1:5000
    • 推荐人政策:降级时无推荐人
  • 响应标头:
    • 允许:POST、OPTIONS、HEAD、GET
    • 内容长度:0
    • 内容类型:文本/html; charset=utf-8
    • 日期:格林威治标准时间 2019 年 9 月 6 日星期五 09:14:46
    • 服务器:Werkzeug/0.15.5 Python/3.7.4
  • 请求标头:
    • 显示临时标题
    • 访问控制请求标头:授权
    • 访问控制请求方法:GET
    • 来源:http://localhost:3000
    • 推荐人:http://localhost:3000/
    • Sec-Fetch-Mode: no-cors
    • 用户代理:Mozilla/5.0(Windows NT 10.0;Win64;x64)AppleWebKit/537.36(KHTML,如 Gecko)Chrome/76.0.3809.132 Safari/537.36

我注意到,当添加授权标头时,Access-Control-Allow-Origin 消失了,而是出现了 Access-Control_Request-Headers。

前端感兴趣的代码如下

import axios from 'axios';
import * as firebase from "firebase/app";
import 'firebase/auth';

const instance = axios.create({
    baseURL: 'http://localhost:5000/',
});

instance.interceptors.request.use(config => {
    const id_token = firebase.auth().currentUser.getIdToken();
    config.headers = { Authorization: id_token}; <---Commenting out this line works
    return config
}, error => {
    return Promise.reject(error);
})
export default instance;

我不知道 CORS 在添加 JWT 后如何或为何无法工作。我怀疑这是因为一旦添加了 JWT,就会有一个飞行前请求。但是我在服务器端没有任何改变,所以我很困惑为什么服务器不会仅仅因为添加了 JWT 就提供合适的 lCORS 响应。

任何指针将不胜感激。

【问题讨论】:

  • 顺便说一句:如果你使用 create-react-app,你可以在你的 package.json 文件中添加一个代理:link

标签: reactjs cors jwt axios flask-restful


【解决方案1】:

您可以在主文件顶部定义 CORS,它将允许所有 CORS 请求

from flask import Flask
from flask_cors import CORS, cross_origin

app = Flask(__name__)
CORS(app)

@app.route("/api/test")
def test_cors():
  return "CORS allowed"

【讨论】:

  • 我使用的是装饰器语法:@cross_origin(origins ='*', expose_headers='Authorization')。不幸的是,它给出了相同的结果
  • 您可以尝试添加 origins 和 support_credentials 吗?
  • 你可以试试没有像上面这样的装饰器吗?
  • 我从 CORS(app) 调用中取出了所有内容(即不是 app 以外的参数)。然后使用没有参数的装饰器(即@cross_origin())并且它正在工作。似乎将参数传递给 CORS() 会干扰某些事情。
  • 很高兴听到这个消息,您也可以删除 @cross_origin,因为当您在文件顶部定义 CORS 时,它将应用您应用的所有路由,请参阅 official docs here!
猜你喜欢
  • 1970-01-01
  • 2017-05-19
  • 2017-07-29
  • 2021-02-21
  • 2019-11-11
  • 2021-07-22
  • 1970-01-01
  • 2020-05-14
相关资源
最近更新 更多