简体   繁体   English

如何在 CORS FastAPI 中间件中正确使用 Regex?

[英]How to properly use Regex in CORS Middleware for FastAPI?

I have an app that uses a FastAPI backend and a Next.js frontend.我有一个使用 FastAPI 后端和 Next.js 前端的应用程序。 In development and on production with stable origins, I am able to use the CORSMiddleware with no issues.在具有稳定来源的开发和生产中,我能够毫无问题地使用 CORSMiddleware。 However, I have deployed the Next.js frontend with Vercel, and want to take advantage of the automatic Preview deployments that Vercel makes with each git commit to allow for staging-type qualitative testing and sanity checks.但是,我已经使用 Vercel 部署了 Next.js 前端,并希望利用 Vercel 对每个 git 提交进行的自动预览部署,以允许进行阶段类型的定性测试和健全性检查。

I'm running into CORS issues on the Preview deployments: since each Preview deployment uses an auto-generated URL of the pattern: <project-name>-<unique-hash>-<scope-slug>.vercel.app , I can't add them directly to the allow_origins argument of the CORSMiddleware.我在预览部署中遇到了 CORS 问题:由于每个预览部署都使用自动生成的 URL 模式: <project-name>-<unique-hash>-<scope-slug>.vercel.app ,我可以不要将它们直接添加到 CORSMiddleware 的allow_origins参数中。 Instead I am trying to add the pattern to the allow_origin_regex argument.相反,我试图将模式添加到allow_origin_regex参数中。

I am very new to regex, but was able to figure out a pattern that I've tested to work in REPL.我是正则表达式的新手,但能够找出一种我已经测试过可以在 REPL 中使用的模式。 However, because I'm having issues, I've switched to use an ultra-permissive regex of '.*' just to get anything to work but that has failed also.但是,因为我遇到了问题,所以我转而使用“.*”的超宽容正则表达式,只是为了让任何东西都能正常工作,但也失败了。

main.py (relevant portions) main.py(相关部分)

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

origins = [
    "http://localhost",
    "http://localhost:8080",
    "http://localhost:3000",
    "https://my-project-name.vercel.app"
]

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

I've looked at the FastAPI/Starlette cors.py file to see how it ingests and uses the origin regex and don't see where the problem would be.我查看了 FastAPI/Starlette cors.py 文件,了解它如何摄取和使用原始正则表达式,但没有发现问题出在哪里。 I've tested the same methods in REPL with no issues.我已经在 REPL 中测试了相同的方法,没有任何问题。 I'm at a loss as to the next avenue to investigate in order to resolve this issue.我不知道为解决此问题而进行调查的下一个途径。 Any assistance or pointers or "hey dummy you forgot this" comments are welcome.欢迎任何帮助或指点或“嘿傻瓜你忘了这个”评论。

Whenever a new deployment is created, Vercel will automatically generate a unique URL that is publicly available, and which is composed of the following pieces:每当创建新的部署时,Vercel 都会自动生成一个唯一的 URL ,它是公开的,由以下部分组成:

<project-name>-<unique-hash>-<scope-slug>.vercel.app

To allow requests from any Vercel deployment use:要允许来自任何Vercel 部署的请求,请使用:

allow_origin_regex='https://.*\.vercel\.app'

To allow requests from a specific Vercel project use:要允许来自特定Vercel 项目的请求,请使用:

allow_origin_regex='https://<project-name>-.*\.vercel\.app'

for instance:例如:

allow_origin_regex = 'https://my-site-.*\.vercel\.app'

The example below is based on how FastAPI/Starlette's CORSMiddleware works internally (see implementation here ).下面的示例基于 FastAPI/Starlette 的CORSMiddleware的内部工作方式(参见此处的实现)。 The example shows that using the above regex, a match for an origin such as https://my-site-xadvghg2z-acme.vercel.app is found.该示例显示使用上面的正则表达式,找到了诸如https://my-site-xadvghg2z-acme.vercel.app类的来源的匹配项。

import re

origin = 'https://my-site-xadvghg2z-acme.vercel.app'
allow_origin_regex = 'https://my-site-.*\.vercel\.app'
compiled_allow_origin_regex = re.compile(allow_origin_regex)

if (compiled_allow_origin_regex is not None
        and compiled_allow_origin_regex.fullmatch(origin)):
    print('Math found')
else:
    print('No match found')

Also, please make sure to specify the correct protocol (eg, http , https ) and port ( 80 , 8000 , 3000 ) in allow_origin_regex .另外,请确保在allow_origin_regex中指定正确的协议(例如httphttps )和端口8080003000 )。

I hesitate to admit how stupid the answer to this actually was once I realized my mistake, but wanted to be intellectually honest and provide an update just in case anyone else has a similar blank and runs into this down the line.一旦我意识到我的错误,我就不愿承认这个答案实际上是多么愚蠢,但我想在理智上诚实并提供更新,以防其他人有类似的空白并遇到这个问题。

I'm new to anything frontend and development in general for the most part, and had never really dealt with CORS before.大多数情况下,我对任何前端和开发都是新手,之前从未真正处理过 CORS。 I was so concerned with getting the Preview deployments going on the frontend, and checking the auto-built Preview deployments on Vercel, that I forgot where I was actually making changes.我非常关心在前端进行预览部署,并检查 Vercel 上自动构建的预览部署,以至于我忘记了实际进行更改的位置。 I have the frontend and backend of my project as subdirectories within the same repo, so each git push of the backend code causes an automatic Vercel deployment, and I just blanked that it wouldn't cause an update of the actual FastAPI code.我将项目的前端和后端作为同一存储库中的子目录,因此后端代码的每次 git 推送都会导致自动 Vercel 部署,而我只是空白它不会导致实际 FastAPI 代码的更新。

As soon as I realized and pushed the changes to my backend, everything started working as it should.一旦我意识到并将更改推送到我的后端,一切都开始正常工作。

I marked the other answer as correct because it was 100% correct in answering the question I asked, but providing this as it's the answer to the problem of where I made the real mistake.我将另一个答案标记为正确,因为它在回答我提出的问题时是 100% 正确的,但提供这个是因为它是对我犯了真正错误的问题的答案。

This answer worked for me.这个答案对我有用。 But the problem with that answer is that FASTAPI will accept any response request from any Vercel deployment.但该答案的问题在于 FASTAPI 将接受来自任何 Vercel 部署的任何响应请求。 If you want FASTAPI to enable only requests from your Vercel account, then you could modify allow_origin_regex variable to,如果您希望 FASTAPI 仅启用来自您的 Vercel 帐户的请求,那么您可以将allow_origin_regex变量修改为,

allow_origin_regex = 'https://<YOUR_VERCEL-PROJECT-NAME>-*\.vercel\.app'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM