FastAPI/Starlette中CSRF令牌的正确处理方式咨询
FastAPI/Starlette中CSRF令牌的正确处理方式咨询
我正在搭建一个使用Jinja2模板的FastAPI应用,现在对CSRF令牌的处理方式有点拿不准。我已经添加了Starlette的SessionMiddleware:
app.add_middleware(SessionMiddleware, secret_key="some-random-string")
不过我觉得自己可能用错了,目前的处理流程是:
- 生成一个随机字符串作为令牌,存在session里
- 把这个字符串作为上下文变量传给Jinja2模板
- 打算在请求里把这个字符串作为请求头发送
嘿,你的思路方向是对的,但其实不用这么麻烦,Starlette提供了专门的CSRFMiddleware来帮你自动化处理CSRF令牌的生成、存储和验证,比手动实现更安全也更省心,我给你梳理下正确的操作步骤:
首先,给你的应用加上CSRFMiddleware(记得先确保已经安装了starlette):
from starlette.middleware.csrf import CSRFMiddleware # 先保留你已经加的SessionMiddleware,CSRF依赖它来存储会话信息 app.add_middleware(SessionMiddleware, secret_key="your-strong-random-secret") # 添加CSRF中间件 app.add_middleware(CSRFMiddleware, secret_key="your-strong-random-secret", # 可以和SessionMiddleware的密钥一致,也可单独设置 cookie_name="csrftoken", # 可选,自定义存储令牌的cookie名称 header_name="X-CSRFToken") # 可选,自定义验证时用的请求头名称
接下来的流程就完全自动化了:
- 自动生成令牌:用户第一次访问你的应用时,
CSRFMiddleware会自动生成一个安全的CSRF令牌,并存入用户的会话(或你指定的cookie)中,不用你手动去生成和保存。 - 在模板中使用令牌:令牌会自动挂载到请求对象的
csrf_token属性上,你直接在Jinja2模板里调用就行:- 如果是表单提交,把令牌作为隐藏字段放入表单:
<form method="post" action="/submit-form"> <input type="hidden" name="csrf_token" value="{{ request.csrf_token }}"> <!-- 你的其他表单字段 --> <button type="submit">提交</button> </form> - 如果是AJAX请求,就把令牌放到请求头里:
const csrfToken = document.querySelector('input[name="csrf_token"]').value; fetch('/api/data', { method: 'POST', headers: { 'X-CSRFToken': csrfToken, 'Content-Type': 'application/json' }, body: JSON.stringify({/* 你的请求数据 */}) });
- 如果是表单提交,把令牌作为隐藏字段放入表单:
- 自动验证令牌:
CSRFMiddleware会自动拦截所有修改型请求(POST、PUT、DELETE等),检查请求中的令牌和会话里的是否一致,不一致就直接返回403错误,完全不用你手动写验证逻辑。
最后提醒你:secret_key一定要用足够复杂的随机字符串,别用示例里的"some-random-string",可以用Python的secrets.token_hex(32)生成一个安全的密钥,避免被破解。
内容来源于stack exchange
相关产品推荐
相关产品推荐

