2014-12-07 58 views
2

我正在使用Django Rest框架。在权限类中,我检查两个自定义http头的值:mt_api_tokenmt_api_key自定义HTTP标头是不同的测试和httpie

在测试中,我使用自定义标题调用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 _...']我的测试失败。

回答

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来修复测试,这些键是通过浏览器传入时的内容。您还需要调整视图代码以引用这些新密钥。

+0

嗨@kevinbrown我不想改变sign_request方法,但没有确定它是否合理。感谢这个奇妙的解释 – 2014-12-08 20:50:48