首页 > 解决方案 > TokenAuthentication 对象没有属性“get_user”

问题描述

我正在尝试使用包含 django-rest-knox 生成的令牌的授权标头对用户进行身份验证。我还有另外两个身份验证后端。为此,我调用了 knox.auth 中定义的 authenticate() 方法。但是,它返回此错误并且无法对用户进行身份验证:WrappedAttributeError at /login/ 'TokenAuthentication' object has no attribute 'get_user' 如果我为从 TokenAuthentication 继承的类定义 get_user() 方法并改用该类,则会得到修复。有什么我可以修复的,这样我就不必实现它或找出触发这个函数调用的中间件?

视图.py

from django.contrib.auth.models import User
from rest_framework.response import Response
from knox.views import LoginView as KnoxLoginView
from knox.auth import TokenAuthentication

class GetAuthToken(KnoxLoginView):
    permission_classes = [AllowAny]

    def post(self, request,*args, **kwargs):
        user = TokenAuthentication().authenticate(request=request)
        if user:
            return Response(status=200)
        else:
            requestToken = request.data.get('requestToken')
            if not requestToken:
                return Response({'result': 'error'})

            user = User.objects.all().first()
            if user is None:  
                return super().post(request, format=None)
            else:
                login(request, user, backend='knox.auth.TokenAuthentication')
                return super().post(request, format=None)
        return super().post(request, format=None)

设置.py

    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'adminutil',
    'advisory',
    'knox',
]
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend',
    'knox.auth.TokenAuthentication',
    'rest_framework.authentication.SessionAuthentication'
]
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES' : [
        'knox.auth.TokenAuthentication',
        'rest_framework.authentication.SessionAuthentication'
    ]
}

这些是服务器日志:

[01/Oct/2019 16:33:58] "POST /login/ HTTP/1.1" 200 160
Internal Server Error: /login/
Traceback (most recent call last):
  File "/home/shaily/.local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/home/shaily/.local/lib/python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/shaily/.local/lib/python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/shaily/.local/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/shaily/.local/lib/python3.6/site-packages/django/views/generic/base.py", line 71, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/shaily/.local/lib/python3.6/site-packages/rest_framework/views.py", line 505, in dispatch
    response = self.handle_exception(exc)
  File "/home/shaily/.local/lib/python3.6/site-packages/rest_framework/views.py", line 465, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/home/shaily/.local/lib/python3.6/site-packages/rest_framework/views.py", line 476, in raise_uncaught_exception
    raise exc
  File "/home/shaily/.local/lib/python3.6/site-packages/rest_framework/views.py", line 493, in dispatch
    self.initial(request, *args, **kwargs)
  File "/home/shaily/.local/lib/python3.6/site-packages/rest_framework/views.py", line 410, in initial
    self.perform_authentication(request)
  File "/home/shaily/.local/lib/python3.6/site-packages/rest_framework/views.py", line 324, in perform_authentication
    request.user
  File "/home/shaily/.local/lib/python3.6/site-packages/rest_framework/request.py", line 220, in user
    self._authenticate()
  File "/usr/lib/python3.6/contextlib.py", line 99, in __exit__
    self.gen.throw(type, value, traceback)
  File "/home/shaily/.local/lib/python3.6/site-packages/rest_framework/request.py", line 78, in wrap_attributeerrors
    raise exc.with_traceback(info[2])
  File "/home/shaily/.local/lib/python3.6/site-packages/rest_framework/request.py", line 74, in wrap_attributeerrors
    yield
  File "/home/shaily/.local/lib/python3.6/site-packages/rest_framework/request.py", line 220, in user
    self._authenticate()
  File "/home/shaily/.local/lib/python3.6/site-packages/rest_framework/request.py", line 373, in _authenticate
    user_auth_tuple = authenticator.authenticate(self)
  File "/home/shaily/.local/lib/python3.6/site-packages/rest_framework/authentication.py", line 123, in authenticate
    if not user or not user.is_active:
  File "/home/shaily/.local/lib/python3.6/site-packages/django/utils/functional.py", line 256, in inner
    self._setup()
  File "/home/shaily/.local/lib/python3.6/site-packages/django/utils/functional.py", line 392, in _setup
    self._wrapped = self._setupfunc()
  File "/home/shaily/.local/lib/python3.6/site-packages/django/contrib/auth/middleware.py", line 24, in <lambda>
    request.user = SimpleLazyObject(lambda: get_user(request))
  File "/home/shaily/.local/lib/python3.6/site-packages/django/contrib/auth/middleware.py", line 12, in get_user
    request._cached_user = auth.get_user(request)
  File "/home/shaily/.local/lib/python3.6/site-packages/django/contrib/auth/__init__.py", line 189, in get_user
    user = backend.get_user(user_id)
rest_framework.request.WrappedAttributeError: 'TokenAuthentication' object has no attribute 'get_user' ```

标签: pythondjangoauthenticationdjango-rest-frameworktoken

解决方案


django-rest-knox,顾名思义,是 Django REST Framework 的身份验证库,而不是 Django 本身。您已将其正确添加到 REST_FRAMEWORK DEFAULT_AUTHENTICATION_CLASSES 设置中,但您也已将其添加到不属于它的主要 Django AUTHENTICATION_BACKENDS 设置中。从那里删除它。


推荐阅读