FastAPI 入门系列 之 中间件!

这是我参与11月更文挑战的第28天,活动详情查看:2021最后一次更文挑战

中间件

有时我们需要对许多路由之前执行相同的操作,比如判断是否拥有权限访问等,这时,我们就可以通过中间件来实现,所谓中间件,其实和 Flask 框架中的请求钩子很类似,实际上是一个函数,在 request 处理之前和 response 返回之前被调用。

中间件处理逻辑:

  • 接收客户端请求
  • 对该请求执行某些自定义操作
  • 传递给应用程序相应的路由继续处理业务逻辑
  • 接收应用程序视图函数返回的响应
  • 对响应进行自定义操作
  • 返回响应

自定义中间件

可以使用 FastAPI 提供的app.middleware("http")装饰器创建中间件。

下面创建一个中间件,用于返回应用程序的处理时间:

@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
复制代码

可见,中间件函数需要接收request请求对象以及call_next函数作为参数,然后call_next函数将request作为参数,然后传递给应用程序相应的路由继续处理并接收响应response,我们可以对response进行操作,最后返回。

我们可以自定义其他功能的中间件,比如请求拦截器等,检验用户访问权限等。

使用已有的的中间件

除了自定义中间件,我们也可以直接使用 FastAPI 自带的中间件,可以通过app.add_middleware()操作来引入已定义的中间件,接收两个参数,第一个参数为中间件的类,第二个参数为要传递给中间件的参数。

下面以HTTPSRedirectMiddleware中间件和TrustedHostMiddleware中间件为例,其中HTTPSRedirectMiddleware强制发来的请求协议必须是 https 或者 wss;TrustedHostMiddleware强制发来的请求必须在 Header 信息中设置了 Host 选项,为了避免 HTTP Host Header 攻击。

app.add_middleware(HTTPSRedirectMiddleware)
app.add_middleware(
    TrustedHostMiddleware, allowed_hosts=["tigeriaf.com", "*.tigeriaf.com"]
)
复制代码

另外,还有一些其他功能的中间件,可参考文档:Starlette's Middleware docs  

使用CORSMiddleware中间件解决跨域问题

开发接口服务,跨域问题也算是很常见的一个问题了,通常我们的 API 一般是给到前端去调用,但是前端和后端往往可能属于不同的源,所以需要做跨域请求支持,FastAPI通过CORSMiddleware中间件来实现。

origins = [
    "http://localhost",
    "http://localhost:8080",
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
复制代码

CORSMiddleware中间件支持的参数部分如下:

  • allow_origins:允许跨域请求的域名列表
  • allow_methods:允许跨域请求的HTTP方法列表,默认只支持GET,["\*"]表示允许所有 HTTP 方法
  • allow_headers:跨域请求支持的HTTP头信息列表。['*']表示允许所有头信息
  • allow_credentials:表示在跨域请求时是否支持cookie,默认为False
  • expose_headers:表示对浏览器可见的返回结果头信息,默认为[]
  • max_age:浏览器缓存CORS返回结果的最大时长,默认为600秒

总之,我们可以通过 FastAPI 提供的中间件灵活快速的实现拦截器、权限校验等功能。

原创不易,如果小伙伴们觉得有帮助,麻烦点个赞再走呗~

最后,感谢女朋友在工作和生活中的包容、理解与支持 !

猜你喜欢

转载自juejin.im/post/7035788888450793485