不正确的 Access-Control-Allow-Origin 被自动添加到 POST & DELETE 端点

Incorrect Access-Control-Allow-Origin being added automatically to POST & DELETE endpoints

我有一个使用 FastAPI 构建的应用程序托管在 API Gateway 使用 serverless.

API:https://xxxxx.execute-api.xx-xxxxxx-x.amazonaws.com/dev/{proxy+}

由于我的大部分端点都是代理端点,我将按如下方式添加到 response headers

response.headers['Access-Control-Allow-Origin'] = "*"
response.headers['Access-Control-Allow-Credentials'] = "true"
response.headers['Access-Control-Allow-Headers'] = "Origin, X-Requested-With, Content-Type, Accept, x-access-token"

我有 3 种不同类型的端点:GET、POST 和 DELETE。

在GET请求中正确分配了Access-Control-Allow-Origin如下:

access-control-allow-credentials: true 
access-control-allow-headers: Origin,X-Requested-With,Content-Type,Accept,x-access-token 
access-control-allow-origin: * 
content-length: 150 
content-type: application/json 
date: Mon,09 Aug 2021 07:06:45 GMT 
x-amz-apigw-id: DyYQPFBHFiAFrQA= 
x-amzn-remapped-content-length: 150 
x-amzn-requestid: 24fac4dc-189c-468e-9ca7-1bfd6ccfbabe 
x-amzn-trace-id: Root=1-6110d401-2816fc3630142ecd24604935;Sampled=0 

它在 POST 和 DELETE 方法中的分配不正确。当我在 API 网关上托管它时,above-mentioned API 会自动添加到 Access-Control-Allow-Origin 中以代替 "*"如上所示声明响应 headers。

POST 和 DELETE 方法的响应 headers:

access-control-allow-credentials: true 
access-control-allow-headers: Origin,X-Requested-With,Content-Type,Accept,x-access-token  access-control-allow-methods: GET,POST,DELETE 
access-control-allow-origin: https://xxxxx.execute-api.xx-xxxxxx-x.amazonaws.com/dev/{proxy+} 
content-length: 392 
content-type: application/json 
date: Mon,09 Aug 2021 07:01:37 GMT 
x-amz-apigw-id: DyXgoHozliAFnJA= 
x-amzn-remapped-content-length: 392 
x-amzn-requestid: a03fad7e-1caf-4a8c-b188-932923085755 
x-amzn-trace-id: Root=1-6110d2d0-39fe47e07531d93a585117d7;Sampled=0 

因此,前端显示以下错误:

Failed to load resource: Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin.

我是否缺少应该为这些方法添加的内容?

谢谢

编辑 1:

我将对所有端点的响应设置为 headers,如下所示:

from fastapi import APIRouter

router = APIRouter(
    prefix="/dimensioning",
    tags=["dimensioning"],
)

@router.post('/')
def post_body(response: Response):
    response.headers['Access-Control-Allow-Origin'] = "*"
    response.headers['Access-Control-Allow-Credentials'] = "true"
    response.headers['Access-Control-Allow-Headers'] = "Origin, X-Requested-With, Content-Type, Accept, x-access-token"
    response.headers['Content-Type'] = "application/json"
    # do the other stuff

@router.get('/')
def get_body(response: Response):
    response.headers['Access-Control-Allow-Origin'] = "*"
    response.headers['Access-Control-Allow-Credentials'] = "true"
    response.headers['Access-Control-Allow-Headers'] = "Origin, X-Requested-With, Content-Type, Accept, x-access-token"
    response.headers['Content-Type'] = "application/json"
    # do the other stuff

@router.delete('/')
def delete_body(response: Response):
    response.headers['Access-Control-Allow-Origin'] = "*"
    response.headers['Access-Control-Allow-Credentials'] = "true"
    response.headers['Access-Control-Allow-Headers'] = "Origin, X-Requested-With, Content-Type, Accept, x-access-token"
    response.headers['Content-Type'] = "application/json"
    # do the other stuff

我也是按照结构here. So in my main.py, as done here,我有

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

编辑 2

当我检查响应时,我看到有 2 个 APIs:

这是针对 POST(没有我提到的响应 headers)

这是针对 OPTIONS 方法

此错误可能与 CORS 规范有关。

根据 CORS specification,您不能将 Access-Control-Allow-Credentials=trueAccess-Control-Allow-Origin=* 结合使用,因为它指出:

When responding to a credentialed request, the server must specify an origin in the value of the Access-Control-Allow-Origin header, instead of specifying the "*" wildcard.

CORS 高度依赖于客户端的实现,在本例中还依赖于 API 管理器,GET 请求的处理方式与 POST 和处理其他请求。如果您想支持本地主机进行开发,您可能必须在代码中或使用 API 网关配置为 Access-Control-Allow-Origin header 显式设置正确的值。

在这个问题上花了几个小时并与前端开发人员协调后,我们意识到前端缺少后端所需的参数。它导致内部服务器错误,这就是 headers 不可用的原因。

添加参数后,请求成功