现在有一个实际的问题,我们在完成某一个项目的时候,如果说用户非要从接口传递一些非法参数或者某些人想要搞破坏,传递恶意的参数。如果参数直接与数据库相关,恶意传入一些参数会直接影响到数据库的正常运行,所以我们该怎么处理这些非法参数呢?写个函数验证?但是接口那么多,无穷尽也。但是fastapi提供了一些优雅的解决方式!

额外的校验

下面是一段代码:

1
2
3
4
5
6
7
8
9
10
from typing import Optional

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/router/")
async def read_items(q: Optional[str] = None):
pass

需求是限制参数q的长度

Query

官方提供了一个库叫做Query,这个库可以非常简单的做校验,如下:

1
2
3
4
5
6
7
8
9
10
from typing import Optional

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/router/")
async def read_items(q: Optional[str] = Query(None, max_length=50)):
pass

功能

我们直接从源码上看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def Query(  # noqa: N802
default: Any,
*,
alias: Optional[str] = None,
title: Optional[str] = None,
description: Optional[str] = None,
gt: Optional[float] = None,
ge: Optional[float] = None,
lt: Optional[float] = None,
le: Optional[float] = None,
min_length: Optional[int] = None,
max_length: Optional[int] = None,
regex: Optional[str] = None,
example: Any = Undefined,
examples: Optional[Dict[str, Any]] = None,
deprecated: Optional[bool] = None,
include_in_schema: bool = True,
**extra: Any,
) -> Any:

其实根据翻译就能够得出这些参数大概是什么意思,如gt、ge、lt、le分别是大于、大于等于、小于、小于等于。但是其中有一个功能却十分强大,即regex

是的,参数校验可以使用正则表达式,在官方给定的案例中,我们可以看到正则表达式的使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from typing import Optional

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
q: Optional[str] = Query(None, min_length=3, max_length=50, regex="^fixedquery$")
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results

这个指定的正则表达式通过以下规则检查接收到的参数值:

  • ^:以该符号之后的字符开头,符号之前没有字符。
  • fixedquery: 值精确地等于 fixedquery。
  • $: 到此结束,在 fixedquery 之后没有更多字符。

当然,别名参数alias也是十分有用的,如果你不想让调用函数的人通过参数揣测你的接口含义,你可以通过给参数命别名的方式来混淆别人对函数的判断,从而保证函数的安全。当然,别名也可以使得参数更加规范,或许?