一文掌握异步web框架FastAPI(四)-- 中间件(添加回包数据、请求计时、用户代理、跨域资源共享CORS、请求限制、请求体大小限制、响应缓存、安全头、数据库事务管理)

接上篇:一文掌握异步web框架FastAPI(三)-CSDN博客

目录

七、中间件

 6、添加回包数据中间件

7、请求计时中间件

8、用户代理中间件

9、跨域资源共享 (CORS) 中间件

1)同源策略:

2)CORS的工作原理:

3)简单请求

4)预检请求

5)fastapi实现CORS

10、请求限制中间件

1)使用aiocache来缓存请求计数

2)使用redis

11、请求体大小限制中间件

12、响应缓存中间件

13、安全头中间件

14、数据库事务管理中间件


七、中间件

 6、添加回包数据中间件

from fastapi import FastAPI, Request
import logging
import json

logging.basicConfig(level=logging.INFO)

app = FastAPI()


@app.middleware("http")
async def log_body(request: Request, call_next):
    response = await call_next(request)

    # 捕获响应体内容
    body = b""
    async for chunk in response.body_iterator:
        body += chunk
    # 打印body
    logging.info(f"Response body: {body.decode('utf-8')}")

    # 打印body类型
    logging.info(f"body type: {type(body.decode('utf-8'))}")

    # 解析body为dict
    body_dict = json.loads(body.decode('utf-8'))

    # 新增数据
    body_dict.update({'name': 'jack'})

    # 将修改后的body重新编码为bytes
    body = json.dumps(body_dict).encode('utf-8')

    # 更新响应体长度
    response.headers["Content-Length"] = str(len(body))

    # 创建一个新的异步生成器来返回处理后的内容
    async def async_iterate():
        yield body

    response.body_iterator = async_iterate()
    return response


@app.get("/")
async def read_root():
    return {"Hello": "World"}

请求:

import requests

# 设置请求的URL
url = "http://127.0.0.1:8000/"

# 发送GET请求
response = requests.get(url)

# 输出响应内容
print("状态码:", response.status_code)  # 打印状态码
print('headers: ', response.headers)
print("响应体:", response.text)  # 打印响应的JSON内容

输出:

原接口返回的是{"Hello": "World"},通过在中间件中新加了body数据,最后返回{"Hello": "World", "name": "jack"},通过这个过程,可以更直观的看到中间件的运行过程和对中间件回包的处理。

7、请求计时中间件

这个中间件用于记录每个请求的处理时间,这对于性能分析很有帮助。

from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
import time

app = FastAPI()

@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    start_time = time.time()
    response = await call_next(request)
    process_time = time.time() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response

@app.get("/")
async def root():
    time.sleep(1)  # 模拟耗时操作
    return {"message": "Hello World"}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

请求:

import requests

# 设置请求的URL
url = "http://127.0.0.1:8000/"

# 发送GET请求
response = requests.get(url)

# 输出响应内容
print("状态码:", response.status_code)  # 打印状态码
print('headers: ', response.headers)
print("响应体:", response.text)  # 打印响应的JSON内容

8、用户代理中间件

这个中间件用于检查请求的 User-Agent 字段,确保请求来自合法的客户端。

from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse

app = FastAPI()

@app.middleware("http")
async def check_user_agent(request: Request, call_next):
    user_agent = request.headers.get("User-Agent")
    if user_agent and "Mozilla" in user_agent:
        return await call_next(request)
    return JSONResponse(status_code=403, content={"error": "Invalid User-Agent"})

@app.get("/headers/")
async def root():
    return {"message": "Hello World"}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

不传User-Agent或传的User-Agent不是Mozilla,返回403

import requests

# 设置请求的URL
url = "http://127.0.0.1:8000/headers/"

# 发送GET请求
response = requests.get(url)

# 输出响应内容
print("状态码:", response.status_code)  # 打印状态码
print('headers: ', response.headers)
print("响应体:", response.json())  # 打印响应的JSON内容

传带Mozilla的User-Agent

import requests

# 设置请求的URL
url = "http://127.0.0.1:8000/headers/"

# 发送GET请求
response = requests.get(url, headers={"User-Agent": "Mozilla/5.0"})

# 输出响应内容
print("状态码:", response.status_code)  # 打印状态码
print('headers: ', response.headers)
print("响应体:", response.json())  # 打印响应的JSON内容

9、跨域资源共享 (CORS) 中间件

跨域资源共享(CORS,Cross-Origin Resource Sharing)是一种安全措施,它允许或拒绝Web应用从其他源域请求资源。这种机制是由Web浏览器实现的,以防止恶意网站读取另一个网站的敏感数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值