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

Flask+Auth0单元测试请求无200状态码及预期行为问题排查

解决Flask+Auth0单元测试中302重定向问题

核心问题分析

测试请求被重定向,说明@requires_auth装饰器未认可传入的Bearer令牌,未通过认证触发了Auth0的重定向逻辑;同时HTTP连接代码存在语法错误与连接管理问题,导致CannotSendRequest和socket.gaierror错误。


步骤1:修正令牌获取代码

原代码存在引号不匹配、硬编码JSON易出错、未关闭连接等问题,修正后:

import http.client
import json

# 修正域名格式与引号问题
conn = http.client.HTTPSConnection("api-name.auth0.com")

# 用json.dumps生成payload,避免转义错误
payload = json.dumps({
    "client_id": "MY_CLIENT_ID",
    "client_secret": "MY_CLIENT_SECRET",
    "audience": "MY_AUD",
    "grant_type": "client_credentials"
})

headers = {'content-type': "application/json"}

conn.request("POST", "/oauth/token", payload, headers)
res = conn.getresponse()
data = res.read()
conn.close()  # 关闭连接,避免CannotSendRequest错误

decoded_data = data.decode("utf-8")
response_json = json.loads(decoded_data)
access_token = response_json.get('access_token')
auth_headers = {'Authorization': f'Bearer {access_token}'}

步骤2:修正Pytest测试逻辑

问题根源

路由代码直接从session读取用户信息,但client credentials模式的令牌是机器身份,不会自动填充session;同时测试中重复设置认证头可能导致冲突。

方案A:Mock认证装饰器(单元测试推荐)

单元测试聚焦路由逻辑,跳过真实Auth0校验:

import pytest
from unittest.mock import patch

@pytest.fixture
def client():
    app.testing = True
    # Mock requires_auth装饰器,直接返回原函数
    with patch('your_app_module.requires_auth', lambda x: x):
        with app.test_client() as client:
            # 模拟session中的用户信息,匹配路由取值
            with client.session_transaction() as sess:
                sess[constants.PROFILE_KEY] = {
                    "user_id": "test-user-123"
                }
            yield client

def test_route(client):
    response = client.get("/route")
    assert b"<h2>Upload</h2>" in response.data
    assert response.status_code == 200

方案B:适配真实Auth0认证(集成测试用)

若需真实认证,需确保@requires_auth支持client credentials令牌并填充session,同时正确传递请求头:

@pytest.fixture
def auth_headers():
    # 生成认证令牌
    import http.client
    import json
    conn = http.client.HTTPSConnection("api-name.auth0.com")
    payload = json.dumps({
        "client_id": "MY_CLIENT_ID",
        "client_secret": "MY_CLIENT_SECRET",
        "audience": "MY_AUD",
        "grant_type": "client_credentials"
    })
    headers = {'content-type': "application/json"}
    conn.request("POST", "/oauth/token", payload, headers)
    res = conn.getresponse()
    data = res.read()
    conn.close()
    response_json = json.loads(data.decode("utf-8"))
    access_token = response_json.get('access_token')
    return {'Authorization': f'Bearer {access_token}'}

@pytest.fixture
def client():
    app.testing = True
    with app.test_client() as client:
        yield client

def test_route(client, auth_headers):
    response = client.get("/route", headers=auth_headers)
    assert response.status_code == 200
    assert b"<h2>Upload</h2>" in response.data

步骤3:解决其他API调用错误

  • socket.gaierror:确认Auth0租户域名拼写正确(如替换为your-tenant.us.auth0.com格式)
  • CannotSendRequest:每次请求后调用conn.close(),或每次请求创建新的连接对象,避免重复使用同一连接

关键注意点

  • 单元测试优先用Mock认证,避免依赖外部服务,提升测试稳定性与速度,避免GitHub Actions中因网络或Auth0限流失败
  • 路由依赖session用户信息的逻辑,与client credentials机器身份的认证流程不匹配,这是重定向的核心原因

内容的提问来源于stack exchange,提问作者mlsmzk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 20:05:39