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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 16:15:39