Django TokenAuthentication 缺少“授权”http 标头

Posted

技术标签:

【中文标题】Django TokenAuthentication 缺少“授权”http 标头【英文标题】:Django TokenAuthentication missing the 'Authorization' http header 【发布时间】:2013-02-13 07:52:53 【问题描述】:

我正在尝试将 TokenAuthentication 与我的一种观点一起使用。 正如https://www.django-rest-framework.org/api-guide/authentication/ 中所述,我将从登录中收到的令牌添加为 HTTP 标头,在我发送的请求中称为:'Authorization'。

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

我正在使用的视图:

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

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

将标头更改为“HTTP_AUTHORIZATION”似乎可行,但感觉有些不对劲。

我错过了什么吗?

【问题讨论】:

【参考方案1】:

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

您的代码可以在开发环境中正常工作(使用runserver),但如果您在 WSGI 服务器(在我的例子中是 Apache)中尝试它,服务器可以去掉授权标头!

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

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

【讨论】:

博客链接已失效,但该提示挽救了我的理智。不知道 Apache/WSGI 正在剥离标头!【参考方案2】:

查看 TokenAuthentication 类,我看到正在检查的标头是“HTTP_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

编辑

关于在 request.META 中查找标头的 Django 文档:

如上所述,除了 CONTENT_LENGTH 和 CONTENT_TYPE, 请求中的任何 HTTP 标头都通过以下方式转换为 META 键 将所有字符转换为大写,将任何连字符替换为 下划线并在名称中添加 HTTP_ 前缀。因此,例如,一个 名为 X-Bender 的标头将映射到 META 键 HTTP_X_BENDER。

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

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

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

【讨论】:

以上是关于Django TokenAuthentication 缺少“授权”http 标头的主要内容,如果未能解决你的问题,请参考以下文章

Django之路

Django系列

django 错误

mac电脑安装django ,运行django报错解决

Django 大神带你飞系列~走进Django

django的文档