如何在AWS Cognito与GraphQL环境下开展单元测试?
解决AWS Cognito令牌校验下的GraphQL测试问题
针对你在测试GraphQL接口时遇到的AWS Cognito idToken校验瓶颈,提供三种可行方案,结合你的现有代码调整:
方案一:测试环境跳过令牌校验(快速验证业务逻辑)
如果你的认证逻辑通过中间件实现,可在测试环境临时禁用校验,直接模拟已登录状态。
假设你有Cognito认证中间件,测试时通过环境变量跳过:
# 测试文件中添加 import os os.environ["TEST_SKIP_COGNITO_AUTH"] = "True" # 修改认证中间件示例 class CognitoAuthMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): if os.getenv("TEST_SKIP_COGNITO_AUTH") == "True": # 模拟登录用户,设置request.user或自定义属性 request.user = User.objects.get(username="test_user") return self.get_response(request) # 原有认证逻辑...
修改测试fixture,无需额外传令牌:
@pytest.fixture def client_query(client): def func(*args, **kwargs): return graphql_query(*args, **kwargs, client=client) return func
方案二:生成模拟JWT令牌(无需调用Cognito服务)
用pyjwt库生成符合Cognito格式的测试令牌,让认证中间件接受该令牌。
先安装依赖:
pip install pyjwt
修改测试代码,生成令牌并添加到请求头:
import json import pytest import jwt from datetime import datetime, timedelta from graphene_django.utils.testing import graphql_query @pytest.fixture def client_query(client): def func(*args, headers=None, **kwargs): headers = headers or {} # 构造匹配Cognito结构的JWT payload payload = { "sub": "test-user-id", "username": "test_user", "exp": datetime.utcnow() + timedelta(hours=1), "iss": "https://cognito-idp.your-region.amazonaws.com/your-user-pool-id", "aud": "your-client-id" } # 用测试密钥签名,需确保中间件在测试环境接受该签名 token = jwt.encode(payload, "test-secret-key", algorithm="HS256") headers["Authorization"] = f"Bearer {token}" return graphql_query(*args, headers=headers, client=client, **kwargs) return func def test_some_query(client_query): response = client_query( ''' query GetAllProjectConfig{ getAllProjectConfig{ project{ id slug name } config{ id } } } ''' ) content = json.loads(response.content) assert 'errors' not in content
注意:需调整认证中间件,在测试环境允许使用测试密钥验证令牌,或关闭签名校验(仅限测试环境)。
方案三:调用Cognito API获取真实测试令牌(集成测试)
若需更真实的测试场景,创建Cognito测试用户,调用API获取真实idToken。
import json import pytest import boto3 from graphene_django.utils.testing import graphql_query @pytest.fixture def cognito_test_token(): # 初始化Cognito客户端 client = boto3.client('cognito-idp', region_name='your-region') # 测试用户登录 response = client.initiate_auth( ClientId='your-client-id', AuthFlow='USER_PASSWORD_AUTH', AuthParameters={ 'USERNAME': 'test-username', 'PASSWORD': 'test-password' } ) return response['AuthenticationResult']['IdToken'] @pytest.fixture def client_query(client, cognito_test_token): def func(*args, **kwargs): headers = { "Authorization": f"Bearer {cognito_test_token}" } return graphql_query(*args, headers=headers, client=client, **kwargs) return func def test_some_query(client_query): response = client_query( ''' query GetAllProjectConfig{ getAllProjectConfig{ project{ id slug name } config{ id } } } ''' ) content = json.loads(response.content) assert 'errors' not in content
注意:需确保测试用户存在于Cognito用户池,且boto3配置了正确权限(测试环境建议用IAM角色或本地配置)。
内容的提问来源于stack exchange,提问作者Titus
相关产品推荐
相关产品推荐

