microdot.csrf --- CSRF 防护¶
拒绝源自跨站点的状态变更请求。该检查作为 before_request 钩子运行,并使用浏览器提供的 Sec-Fetch-Site 标头(在与 microdot.cors.CORS 实例配合使用时,对较旧的浏览器以 Origin 标头作为回退)。
class CSRF¶
- class microdot.csrf.CSRF(app: Microdot | None = None, cors=None, protect_all: bool = True, allow_subdomains: bool = False)¶
- app
要安装到的
microdot.Microdot实例。可选;如果未给出,可稍后调用initialize()。- cors
定义应用程序受信任源的
microdot.cors.CORS实例。对于在不发送Sec-Fetch-Site的浏览器上回退到Origin标头而言是必需的。可选;不提供时,仅应用Sec-Fetch-Site检查。- protect_all
如果为
True(默认),则除GET、HEAD和OPTIONS之外的每个路由都会被自动保护。可以用exempt()单独豁免路由。如果为False,则默认不保护任何路由,由各个路由用protect()选择性加入。- allow_subdomains
如果为
True,则接受来自应用程序源的子域的请求(same-site的 Sec-Fetch-Site,或匹配的源后缀)。
- exempt(f)¶
使路由免于 CSRF 防护的装饰器。将其直接置于路由装饰器之后:
@app.post('/webhook') @csrf.exempt async def webhook(request): # accepts cross-site POSTs
- protect(f)¶
对原本会被豁免的路由(例如
GET路由,或protect_all=False时的每个路由)强制启用 CSRF 防护的装饰器。
示例:
from microdot import Microdot
from microdot.cors import CORS
from microdot.csrf import CSRF
app = Microdot()
cors = CORS(app, allowed_origins=['https://app.example.com'])
csrf = CSRF(app, cors=cors)
@app.post('/api/save')
async def save(request):
# automatically CSRF-protected
return {'ok': True}
当 Sec-Fetch-Site 报告 same-origin 或 none(或在 allow_subdomains=True 时报告 same-site)时,请求被允许。如果该标头不存在,则将请求的 Origin 与 CORS 允许列表进行匹配。两个标头都没有的请求会被接受(对于不受浏览器 CSRF 约束的直接 API 调用而言是典型情况)。