使用带有令牌身份验证的 django permissions.IsAuthenticatedOrReadOnly

using django permissions.IsAuthenticatedOrReadOnly with token authentication

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

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

我的休息框架设置是

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

有办法解决这个问题吗?感谢任何帮助,谢谢

好吧,我只是决定尝试一些东西,它似乎可以正常工作,至少目前是这样。我不知何故相信 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

如果 headers

中存在令牌,则让用户出现在我的视图中
@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)

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

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

如您所见,我没有对请求进行身份验证(未传递任何令牌)并且 headers 按权限打印。

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

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