47

使用Django REST API,我正在尝试验证我的请求。

这就是我要发送的内容:

Content-Type: application/json, Authentication: token="6d82549b48a8b079f618ee9c51a6dfb59c7e2196"

这是我回来的:

{"detail": "Authentication credentials were not provided."}

有人可以给我正确的标题吗?

谢谢

标题:

Accept: application/json
Content-Type: application/json
Authorization: Token 6d82549b48a8b079f618ee9c51a6dfb59c7e2196
Connection: keep-alive
Origin: chrome-extension: //rest-console-id
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.57 Safari/537.17

在此处输入图像描述

设置.py

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.permissions.IsAdminUser',


    ),
    'PAGINATE_BY': 10
}

视图.py

class ProfileList(generics.ListCreateAPIView):
    """
    API endpoint that represents a list of users.
    """
    permission_classes = (permissions.IsAuthenticated,)
    model = Profile
    serializer_class = ProfileSerializer

    def pre_save(self, obj):
        obj.owner = self.request.user
4

6 回答 6

114

以防万一其他人遇到此错误。如果您使用 mod_wsgi 在 Apache 上运行 Django,也会发生这种情况,因为授权标头已被 mod_wsgi 剥离。您需要将以下内容添加到您的 VirtualHost 配置中:

WSGIPassAuthorization On

于 2013-02-27T17:50:38.647 回答
30

假设您尝试使用 TokenAuthentication,标头应如下所示:

Authorization: Token 6d82549b48a8b079f618ee9c51a6dfb59c7e2196

文档中所述

于 2013-02-14T15:09:33.410 回答
20

我的令牌身份验证遇到了同样的问题

这解决了我的问题

设置.py

REST_FRAMEWORK = {
   'DEFAULT_AUTHENTICATION_CLASSES': (
       'rest_framework.authentication.TokenAuthentication',
   ),
   'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAdminUser'
   ),
   'PAGINATE_BY': 10,
}
于 2013-06-19T02:20:51.020 回答
8

就我而言,这是可行的:
(Django REST Framework v3)

设置.py

REST_FRAMEWORK = {
   'DEFAULT_AUTHENTICATION_CLASSES': (
       'rest_framework.authentication.TokenAuthentication',
       'rest_framework.authentication.SessionAuthentication',
   ),
   'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
   ),
}

视图.py

class Test(APIView):
    def get(self, request, format=None):   
        return Response({'Result': 'OK'})

网址.py

router.add_api_view('test', url(r'^test/', views.Test.as_view(),name='test'))

不要忘记在标头中发送令牌信息:

 Key: Authorization  
 Value: Token 76efd80cd6849ad7d35e04f1cc1eea35bdc20294

要生成令牌,您可以使用以下内容(在代码中的某处):

from rest_framework.authtoken.models import Token            
user = User.objects.get(username='<username>')
token = Token.objects.create(user=user)
print(token.key)
于 2016-05-24T14:25:47.627 回答
2

对于那些在 AWS elastic beanstalk 上的人,你有点卡在 apache 上,除非你有

WSGIPassAuthorization On

正如@Fiver 所提到的,您的标题会被剥离

我没有手动修复此问题并制作新图像,而是制作了一个脚本来检查 conf 文件的最后一行是否是WSGIPassAuthorization On ,如果不是,我们更新它并重新启动服务器

在我的 Django 应用程序中,我有一个带有 sh 文件的配置文件夹

配置/服务器/更新-apache.sh

if [[ $(tac /etc/httpd/conf/httpd.conf | egrep -m 1 .) == $(echo 'WSGIPassAuthorization On') ]];
  then
     echo "Httpd.conf has already been updated"
  else
     echo "Updating Httpd.conf.."
     echo 'WSGIPassAuthorization On' >> /etc/httpd/conf/httpd.conf
     service httpd restart
fi

在我将它提交给 git 之前让它变得可执行

chmod +x configs/server/update-apache.sh

然后在我的 python.config 文件中,我在最后添加命令

.ebextensions/python.config

...
...
container_commands:
    01_migrate:
        command: "python manage.py migrate"
        leader_only: true
    02_collectstatic:
        command: "python manage.py collectstatic --noinput"
    03_change_perm:
        command: "chown -R wsgi:root static"
    03_update_apache:
        command: "sh configs/server/update-apache.sh"

现在,任何启动的新机器都将检查服务器是否已更新,并在需要时进行更新

于 2016-05-18T22:04:36.007 回答
0

我被一个相关问题所困扰,分享解决方案以防它对任何人有用。我们的测试服务器需要整个站点的HTTP Basic Auth,即用户在进行个人登录之前必须通过http auth 对话框登录。这是一个简单的凭证 - 足以让 googlebot 远离。对这些服务器的 API 请求通过在请求中嵌入这些凭据来处理这个问题,即

url = "https://username:somepass@domain.com

问题是,当您这样做时,嵌入的凭证会被无形地转换为 httpAuthorization标头。因此,该标头关键字已被占用,因此无法同时发送Authentication令牌标头,并且 DRF API 返回令人困惑的“未提供凭据”错误。

解决方案是使用 DRF 的自定义身份验证文档并创建一个新的 TokenAuthentication 类继承 DRF。在其中我定义了两个方法:def get_custom_authorization_header()and def authenticate(), where authenticate()calls get_custom_authorization_header(),它覆盖了该auth =行:

auth = request.headers.get("X-Ourcustom-Authorization", b"")

调用代码来测试服务器然后替换

headers = {"Authorization": f"Token {your_token}"}

headers = {"X-OurCustom-Authorization": f"Token {token}"}

于 2021-10-13T22:48:30.593 回答