使用django权限。IsAuthenticatedOrReadOnly和令牌认证

时间:2019-11-18 07:22:47

标签: django django-rest-framework django-generic-views

我有这个Django API视图,我想允许授权和未授权的用户访问它,我已将Django令牌身份验证设置为默认身份验证类,但是,每当我尝试以未经身份验证的用户身份访问该视图时,都会出现错误未经授权:,这很奇怪,因为我正在视图中发出获取请求 我的代码在这里

@api_view(['GET'])
@permission_classes([permissions.IsAuthenticatedOrReadOnly])
def all_Search(request):
    print(request.headers)
    src = request.GET.get('q')

我对rest框架的设置是

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ]
}

是否有解决此问题的方法?将感谢您的帮助

2 个答案:

答案 0 :(得分:1)

我尝试重现您的错误,但失败了。 这是我的配置:

settings.py

INSTALLED_APPS = [
    ...
    'rest_framework',
    'rest_framework.authtoken'

]

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ]
}

urls.py

urlpatterns = [
    path('search/', api.all_search, name="search")

]

api.py

from rest_framework import permissions
from rest_framework.decorators import api_view, permission_classes
from rest_framework.response import Response

@api_view(['GET'])
@permission_classes([permissions.IsAuthenticatedOrReadOnly])
def all_Search(request):
    print(request.headers)
    src = request.GET.get('q')
    return Response()

test.py

from rest_framework import status
from rest_framework.test import APILiveServerTestCase
from rest_framework.reverse import reverse

class TestTokenAuthorization(APILiveServerTestCase):
    def test_can_search_without_token(self):
        url = reverse('search', kwargs={})
        response = self.client.get(url, {}, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

这是测试的结果:

Creating test database for alias 'default'...
System check identified no issues (0 silenced).
{'Cookie': '', 'Content-Type': 'application/octet-stream'}
Destroying test database for alias 'default'...

我正在使用djangorestframework==3.10.3python3.7

如您所见,我没有对请求进行身份验证(没有传递令牌),并且标题按预期从权限中打印出来。

也许您的问题是由代码中的其他原因引起的。尝试在问题中包括更多详细信息。

顺便说一句,您的all_Search函数缺少return Response()

答案 1 :(得分:0)

Okey,我刚刚决定尝试尝试一下,至少在目前看来,它似乎可以正常工作。我以某种方式认为 DEFAULT_AUTHENTICATION_CLASSES 是这种情况下的问题,实际上,这是问题所在,所以我只需要删除

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ]
}

#opt to use
#authentication_classes = [TokenAuthentication, SessionAuthentication]
#in my views that requires authentications

在我的设置中,这还不是全部,但是现在我可以访问已授权或未授权的视图:(具有身份验证令牌)。但这不是默认情况下获得身份验证的用户 所以我做到了

基于给定令牌创建视图以吸引用户

from django.contrib.auth.models import AnonymousUser
from rest_framework.authtoken.models import Token

def get_user(token):
    try:
        token = Token.objects.select_related('user').get(key=token)
        return token.user
    except:
        return AnonymousUser

如果标题中存在令牌,则将用户带入我的视图

@api_view(['GET'])
@permission_classes([permissions.IsAuthenticatedOrReadOnly])
def all_Search(request):
    auth = request.headers.get('Authorization').split(' ')[1]
    key = request.headers.get('Authorization').split(' ')[0]
    if key == 'Token' and auth != 'null': #used null coz my frontend sends null if key is not available
        user = get_user(auth)
        print(user)
相关问题