Django TokenAuthentication缺少'Authorization'http标头

ode*_*fos 16 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,)
Run Code Online (Sandbox Code Playgroud)

将标题更改为"HTTP_AUTHORIZATION"似乎有效,但感觉不对.

我错过了什么吗?

Tom*_*tie 19

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

并不完全正确,在请求做查找时META快译通,它实际上寻找头是用了前述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_前缀.因此,例如,名为X-Bender的标头将映射到META密钥HTTP_X_BENDER.

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

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

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


Des*_*ova 5

汤姆的答案很好,但并不完整.

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

您可以在Boone的博客上找到一个很好的修复,让您的Apache conf在请求中保留Authorization标头并使其工作得很好:

RewriteEngine on
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
Run Code Online (Sandbox Code Playgroud)