默认情况下,FastAPI应用程序不允许来自不同来源的请求。当你有一个前端应用程序与后端API通信,并且它们托管在不同的域或端口上时,在FastAPI中允许来自不同来源的请求是一种常见的场景。这被称为CORS(跨域资源共享),它需要一些配置才能正常工作。这篇实用的文章将向您展示如何在FastAPI中启用CORS。让我们卷起袖子向前走吧!
介绍CORS
CORS(跨来源资源共享,Cross-Origin Resource Sharing) 是一种浏览器机制,用于控制网页从一个源(域、协议和端口)向另一个源请求资源的安全策略。CORS 允许服务器在响应头中设置特定的 HTTP 头(如 Access-Control-Allow-Origin
),以指示浏览器允许哪些跨域请求。
同源策略简介
在深入理解 CORS 之前,首先需要了解同源策略。同源策略是浏览器的一种安全机制,限制了来自不同源的文档或脚本之间的交互。两个 URL 如果协议、域名和端口都相同,则认为是同源;否则,即为跨源。
同源策略的目的:
- 防止恶意网站读取或篡改其他网站的数据。
- 保护用户的隐私和安全。
CORS 的工作原理
当一个网页向不同源的服务器发送请求时,浏览器会自动添加一个 Origin
头,指示请求的来源。服务器根据 Origin
头决定是否允许该请求,并在响应中添加 Access-Control-Allow-Origin
头。
主要步骤:
- 预检请求(Preflight Request):对于某些跨域请求(如带有自定义头部、使用非简单方法如
PUT
或DELETE
),浏览器会先发送一个OPTIONS
请求,询问服务器是否允许该跨域请求。 - 服务器响应:服务器在响应中包含
Access-Control-Allow-Origin
等相关头部,指示浏览器是否允许该请求。 - 实际请求:如果预检通过,浏览器会发送实际的跨域请求,并根据服务器的响应决定是否处理返回的数据。
CORS 相关的 HTTP 头
-
Access-Control-Allow-Origin
:-
指定允许访问资源的源。可以使用具体的域名(如
https://example.com
)或*
表示允许所有源。 -
示例:
Access-Control-Allow-Origin: https://example.com
-
-
Access-Control-Allow-Methods
:-
指定允许的 HTTP 方法(如
GET, POST, PUT
)。 -
示例:
Access-Control-Allow-Methods: GET, POST, PUT
-
-
Access-Control-Allow-Headers
:-
指定允许的自定义请求头。
-
示例:
Access-Control-Allow-Headers: Content-Type, Authorization
-
-
Access-Control-Allow-Credentials
:-
指示是否允许发送凭证信息(如 Cookies)。当设置为
true
时,Access-Control-Allow-Origin
不能使用*
。 -
示例:
Access-Control-Allow-Credentials: true
-
CORS 的类型
- 简单请求(Simple Request):
- 使用
GET
、POST
或HEAD
方法。 - 仅使用
Accept
、Accept-Language
、Content-Language
、Content-Type
(仅限application/x-www-form-urlencoded
、multipart/form-data
、text/plain
)等头。 - 不需要预检请求。
- 使用
- 预检请求(Preflighted Request):
- 不属于简单请求的情况,如使用
PUT
、DELETE
方法,或包含自定义头部。 - 需要先发送
OPTIONS
请求,询问服务器是否允许该跨域请求。
- 不属于简单请求的情况,如使用
CORS 的优缺点
优点:
- 提高了 Web 应用的灵活性,允许不同源之间的资源交互。
- 支持现代 Web 开发中的许多功能,如第三方 API 调用、CDN 资源加载等。
缺点:
- 增加了复杂性,需要服务器端正确配置响应头。
- 可能带来安全隐患,如果配置不当,可能导致跨站请求伪造(CSRF)等攻击。
CORSMiddleware中间件
FastApi中可以启用CORS的最佳方法是使用cor中间件模块。该模块允许您指定API将从跨域请求中接受的允许的源、方法、头和凭据列表。您还可以使用通配符(*)来允许所有的起源、方法或头,但出于安全原因不建议这样做。
一般来说,设置CORS的步骤如下:
- 从fastapi.middleware.cors导入CORSMiddleware 中间件
- 创建一个允许的请求源的列表(作为字符串)
- 使用app.add_middleware()方法将CORSMiddleware作为中间件添加到FastAPI应用程序中
- 将允许的请求源列表和想要配置的任何其他参数(例如allow_credentials, allow_methods或allow_headers)传递给中间件。
让我们看一下下面的例子,以便更清楚地了解。
允许来自域列表的请求
在这个例子中,我们限制FastAPI只接受来自特定来源的传入请求,方法和头的数量有限。
示例代码:
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
# Allow these origins to access the API
origins = [
"http://localhost",
"https://localhost:3000",
"https://tools.domain.com",
"https://www.domain.com",
]
# Allow these methods to be used
methods = ["GET", "POST", "PUT", "DELETE"]
# Only these headers are allowed
headers = ["Content-Type", "Authorization"]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=methods,
allow_headers=headers,
)
@app.get("/")
async def main():
return {"message": "Welcome to My Home"}
允许来自任何域的请求
在某些情况下,特别是在开发和测试软件时,你可能希望从API中删除任何限制。下面的代码演示了如何做到这一点:
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.get("/")
async def main():
return {"message": "Welcome to Sling Academy"}
最后总结
本文介绍了CORS,以及如何在FastApi中通过中间件方式灵活实现。