Flask+pytest模拟登录出现CSRF token缺失错误求助(模板已含CSRF)
问题原因及解决办法
1. 测试请求未携带有效CSRF令牌
浏览器访问登录页时,{{ form.hidden_tag() }}会渲染出包含CSRF令牌的隐藏字段,提交表单时浏览器会自动携带该字段。但用pytest模拟POST请求时,若仅构造用户名和密码的提交数据,会缺失CSRF令牌,触发验证失败。
解决方式:
- 先发送GET请求获取登录页,从响应中提取CSRF令牌后再携带提交:
def test_login(client): # 获取登录页面并提取CSRF令牌 response = client.get('/login') csrf_token = response.data.decode().split('name="csrf_token" value="')[1].split('"')[0] # 携带令牌提交登录请求 response = client.post('/login', data={ 'username': 'test_user', 'password': 'test_pass', 'csrf_token': csrf_token }) assert response.status_code == 302 # 假设登录成功后触发重定向 - 单元测试阶段可临时禁用CSRF保护(专注验证业务逻辑):
def test_login_without_csrf(app, client): app.config['WTF_CSRF_ENABLED'] = False response = client.post('/login', data={ 'username': 'test_user', 'password': 'test_pass' }) assert response.status_code == 302
2. 测试环境未配置SECRET_KEY
Flask-WTF生成CSRF令牌依赖Flask的SECRET_KEY,若测试环境未设置该配置项,即便模板渲染了hidden_tag(),也无法生成有效令牌,导致验证失败。
解决方式:
在测试配置中添加SECRET_KEY:
@pytest.fixture def app(): app = create_app() app.config.update({ "TESTING": True, "SECRET_KEY": "test_secret_key" # 必须配置,用于CSRF令牌生成 }) yield app
3. 未正确使用Flask测试客户端上下文
若测试代码未利用Flask测试客户端的上下文机制,会导致CSRF令牌的生成与验证流程异常。确保使用Flask提供的client fixture,它会自动处理请求上下文。
内容的提问来源于stack exchange,提问作者user20242245
相关产品推荐
相关产品推荐

