Django 测试客户端未提供正确的身份验证标头

vol*_*gas 8 authentication django

当向开发服务器发送请求时,我可以包含一个标头,如下所示:

Authorization: Token efc7fa291f4e320ff4a31cf9a11d6de3a366937cd1ec24e0a7ab68dafa38430f\r\n
Run Code Online (Sandbox Code Playgroud)

在 Django 内部会看到一个HTTP_AUTHORIZATION标头,我不确定它是在哪里生成的。

但是当使用Django测试客户端进行单元测试时:

from django.test import Client

c = Client()
response = c.get('/api/auth/user/', **{'Authorization': 'Token ' + token})
Run Code Online (Sandbox Code Playgroud)

Django 无法授权该请求。

如果我执行以下操作:

response = c.get('/api/auth/user/', **{'HTTP_AUTHORIZATION': 'Token ' + token})
Run Code Online (Sandbox Code Playgroud)

有用。

我想了解发生了什么事。

谁负责执行映射Authorization-> HTTP_AUTHORIZATION

与这个问题相关:我正在使用Django 2.1.5,djangorestframework = "==3.9.0"djangorestframework = "==3.9.0"

dir*_*ten 4

Django 文档是这样说的:

\n\n
\n

通过发送的标头**extra应遵循 CGI 规范。例如,模拟在从浏览器到服务器的 HTTP 请求中发送的不同 \xe2\x80\x9cHost\xe2\x80\x9d 标头应作为 HTTP_HOST 传递。

\n
\n\n

这是相关的 CGI 引用:

\n\n
\n

HTTP_* :

\n\n

这些变量特定于通过 HTTP 发出的请求。\n 这些变量的解释可能取决于\n SERVER_PROTOCOL 的值。

\n\n

如果使用的协议是 HTTP,则名称以“HTTP_”开头的环境变量包含从客户端读取的标头数据。\n HTTP 标头名称将转换为大写,将所有出现的“-”替换为“ ” 并在环境变量名称前面添加“HTTP ”。标头数据可以按客户端发送的方式呈现,或者可以以不改变其语义的方式重写。如果接收到具有相同字段名称的多个标头,则必须将它们重写为具有相同语义的单个标头。同样,在多行上接收的标头必须合并到一行上。如果需要,服务器必须更改数据的表示形式(例如字符集)以使其适合对于 CGI\n 环境变量。

\n
\n\n

这就是 Django 所看到的,因为您的所有请求都由 CGI 兼容的应用服务器处理(实际上是 WSGI,例如gunicorn 和 uwsgi)。所以基本上测试客户端想要一个 CGI 请求,这意味着您必须根据上述规则转换 HTTP 标头。

\n