Django TokenAuthentication缺少'Authorization'http标头

时间:2013-02-27 13:25:07

标签: django authorization django-rest-framework http-token-authentication

我正在尝试将TokenAuthentication与我的一个视图一起使用。 如https://www.django-rest-framework.org/api-guide/authentication/中所述,我将登录时收到的令牌添加为我发送的请求中名为“授权”的HTTP头。

问题是在我的单元测试中,身份验证失败。 查看TokenAuthentication类,我看到正在检查的标头是'HTTP_AUTHORIZATION'而不是'授权'

我正在使用的视图:

class DeviceCreate(generics.CreateAPIView):
    model = Device
    serializer_class = DeviceSerializer

    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

将标题更改为“HTTP_AUTHORIZATION”似乎有效,但感觉不对。

我错过了什么吗?

2 个答案:

答案 0 :(得分:19)

  

查看TokenAuthentication类,我看到正在检查的标头是'HTTP_AUTHORIZATION'而不是'Authorization'

不完全正确,在请求META dict中进行查找时,它实际查找的标头不在HTTP_之前,因此request.META.get('HTTP_AUTHORIZATION', '') 实际上在请求中查找Authorization标头。

  

问题是在我的单元测试中,身份验证失败   将标题更改为“HTTP_AUTHORIZATION”似乎可以正常工作

我没有仔细检查测试客户端的外观,但我相信设置HTTP_AUTHORIZATION是你需要做的,相当于实际设置Authorization标头。如果您实际发出了http请求,您应该会发现设置auth标头的工作方式完全符合您的预期。

请在此处查看request.META文档:https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.META

修改

Django在request.META中查找标题的文档:

  

除了上面给出的CONTENT_LENGTH和CONTENT_TYPE之外,   请求中的任何HTTP标头都将转换为META密钥   将所有字符转换为大写,用。替换任何连字符   下划线并在名称中添加HTTP_前缀。所以,例如,a   名为X-Bender的标题将映射到META密钥HTTP_X_BENDER。

Django有关使用测试客户端设置标头的文档:

  

但是,您可以使用关键字参数来指定一些默认标头。例如,这将在每个请求中发送User-Agent HTTP标头:

     
    
      

c =客户端(HTTP_USER_AGENT ='Mozilla / 5.0')

    
  

答案 1 :(得分:5)

Tom's answer很好,但不完整。

您的代码可以在dev环境中使用runserver),但如果您在WSGI服务器(在我的情况下是Apache)中尝试它,服务器可以删除Authorization标头!

您可以在Boone's Blog上找到一个很好的修补程序,以便您的Apache conf在请求中保留Authorization标头并使其工作正常:

RewriteEngine on
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]