You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Pytest测试集成Flask-WTForms的Flask应用时,POST请求因缺少CSRF令牌验证失败的解决方法

Pytest测试集成Flask-WTForms的Flask应用时,POST请求因缺少CSRF令牌验证失败的解决方法

嗨,我完全懂你遇到的问题——把应用改成用Flask-WTForms后,测试里的POST请求因为没带CSRF令牌直接触发了400错误,之前找到的旧方案还因为Werkzeug版本更新失效了。我给你分享两种可行的解决办法,优先推荐第一种,因为它更贴近真实用户的使用场景。

问题根源

Flask-WTForms默认开启了CSRF保护机制,所有提交的表单必须携带有效的CSRF令牌才能通过验证。你的测试直接提交表单数据,没有包含这个令牌,导致表单验证失败,服务器返回400错误,自然也就没有你预期的重定向Location头,才会抛出BadRequestKeyError。

解决方案一:模拟真实流程获取并携带CSRF令牌(推荐)

我们可以先发送一个GET请求到表单页面,从客户端会话中提取CSRF令牌,再把它加入POST的表单数据里,完美复刻用户的真实操作流程。

修改你的tests/test_auth.py里的test_register函数:

import pytest
from flask import g, session
from flaskr.db import get_db


def test_register(client, app):
    # 先GET请求注册页面,触发CSRF令牌的生成
    get_response = client.get('/auth/register')
    assert get_response.status_code == 200
    
    # 从客户端会话中提取CSRF令牌
    with client.session_transaction() as sess:
        csrf_token = sess['csrf_token']
    
    # 发送POST请求,带上用户名、密码和CSRF令牌
    response = client.post(
        '/auth/register', 
        data={'username': 'a', 'password': 'a', 'csrf_token': csrf_token},
        follow_redirects=True
    )
    
    # 验证请求成功后跳转到登录页
    assert response.request.path == '/auth/login'
    
    # 验证用户确实被创建
    with app.app_context():
        assert get_db().execute(
            "SELECT * FROM user WHERE username = 'a'",
        ).fetchone() is not None

这个方法的核心是用client.session_transaction()上下文管理器访问客户端的会话,Flask-WTF会把生成的CSRF令牌存在会话的csrf_token键里,我们直接取出来用就行。

解决方案二:测试环境临时禁用CSRF保护(快速测试用)

如果你只是想快速跳过CSRF验证完成测试(不推荐长期使用,因为会漏掉CSRF相关的测试覆盖),可以在测试的应用配置里禁用CSRF保护。

修改tests/conftest.py里的app fixture:

@pytest.fixture
def app():
    db_fd, db_path = tempfile.mkstemp()

    app = create_app({
        'TESTING': True,
        'DATABASE': db_path,
        'WTF_CSRF_ENABLED': False  # 临时关闭CSRF保护
    })

    with app.app_context():
        init_db()
        get_db().executescript(_data_sql)

    yield app

    os.close(db_fd)
    os.unlink(db_path)

这样你的测试POST请求就不需要带CSRF令牌了,但记住这只是权宜之计,生产环境还是要保持CSRF保护开启的,所以尽量用第一种方案哦。

备注:内容来源于stack exchange,提问作者jaybee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 11:23:07