【问题标题】:Custom HTTP headers are different for tests and httpie自定义 HTTP 标头对于测试和 httpie 是不同的
【发布时间】:2014-12-07 17:03:51
【问题描述】:

我正在使用 Django Rest 框架。在权限类中,我检查两个自定义 http 标头的值:mt_api_tokenmt_api_key

在测试中,我使用自定义标头调用 API。 sign_request() 返回{'mt_api_key': api_client.client_id, 'mt_api_token': token}

class APIv1SimpleTestCase(APITestCase):
    [...]
    response = self.client.get(url, format='json', **sign_request("", api_client=oauth2_client))

这是一个遗留系统,标题必须有下划线而不是破折号。

权限类:

class AuthPermissions(permissions.BasePermission):
    def is_token_valid(self, request):
        mt_api_token = request.META['mt_api_token']
        [...]

测试通过。 但是,如果我使用 httpie 调用 api:

$ http  :8000/api/v1/endpoint1/ mt_api_key:0a9..66 mt_api_token:7b2...8

我得到 keyError 异常,因为 request.META['mt_api_key']request.META['mt_api_token'] 不存在。

我必须使用request.META['HTTP_MT_API_TOKEN'],根据DRF documentation for request.META,这是有道理的,但我无法找出测试通过的原因。如果我将实现更改为 request.META['HTTP_...'] 我的测试将失败。

【问题讨论】:

    标签: django http-headers django-rest-framework


    【解决方案1】:

    这在测试中运行良好,因为测试手动设置 request.META 键以匹配您传入的内容,mt_api_tokenmt_api_key。您没有看到任何错误,因为这是完全有效的,但与您的期望不符。这在Django advanced testing documentation 中有非常简短的介绍,但基本上额外的参数是directly addedMETA 字典。

    当您的请求通过 Django 提供的 WSGI 处理程序时,任何 HTTP 标头都会自动以 HTTP_ per the WSGI specification 为前缀。这适用于大多数客户端提供的 HTTP 标头,包括 Authorization 标头,它通常用于在 API 上授权用户(使用基本身份验证、OAuth 等),该标头作为 request.META 字典放入 HTTP_AUTHORIZATION .请注意,键也始终为大写,因为 HTTP 标头名称不区分大小写。

    您可以通过让您的sign_request 方法将键返回为HTTP_MT_API_TOKENHTTP_MT_API_KEY 来修复您的测试,这就是它们在通过浏览器时传递的内容。您还需要调整视图代码以引用这些新键。

    【讨论】:

    • 嗨@kevinbrown 我不想在没有确保它合理的情况下更改sign_request 方法。感谢您的精彩解释
    猜你喜欢
    • 1970-01-01
    • 2013-10-06
    • 1970-01-01
    • 2017-08-20
    • 2012-01-17
    • 2012-09-22
    • 1970-01-01
    • 2015-12-26
    • 1970-01-01
    相关资源
    最近更新 更多