模型后端身份验证在使用管理面板时不会收到凭据



我已经用以下配置设置了一个自定义后端:

设置.py;

REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
'users.backends.CustomUserBackend',
'django.contrib.auth.backends.ModelBackend',
),
}
AUTHENTICATION_BACKENDS = ('users.backends.CustomUserBackend',)

后端.py

class CustomUserBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
if username is None:
username = request.data.get("username")
if password is None:
password = request.data.get("password")
....
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None

当通过我的API提交请求时,这会按预期工作,并正确验证用户等。当我尝试登录到管理面板时,问题就来了。我在尝试登录时得到的堆栈跟踪是由尝试访问request.data时的异常引起的,这是因为它不是正确的类型,这对我的逻辑工作方式是正确的。

问题在于这里的身份验证方法;

def authenticate(request=None, **credentials):
"""
If the given credentials are valid, return a User object.
"""
for backend, backend_path in _get_backends(return_tuples=True):
print(backend)
try:
inspect.getcallargs(backend.authenticate, request, **credentials)
except TypeError:
# This backend doesn't accept these credentials as arguments. Try the next one.
continue
try:
user = backend.authenticate(request, )
except PermissionDenied:
# This backend says to stop in our tracks - this user should not be allowed in at all.
break
if user is None:
continue
# Annotate the user object with the path of the backend.
user.backend = backend_path
return user
# The credentials supplied are invalid to all backends, fire signal
user_login_failed.send(sender=__name__, credentials=_clean_credentials(credentials), request=request)

在这里,凭证具有登录数据{'username': 'dan', 'password': '12345'}。如果我正确理解这个方法(我的python知识有限(,它不会在我的后端找到具有正确参数的身份验证方法,所以它会回到默认值?

登录错误的完整堆栈跟踪;

Traceback (most recent call last):
File ".../env/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File ".../env/lib/python3.7/site-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File ".../env/lib/python3.7/site-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File ".../env/lib/python3.7/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func
response = view_func(request, *args, **kwargs)
File ".../env/lib/python3.7/site-packages/django/contrib/admin/sites.py", line 407, in login
return LoginView.as_view(**defaults)(request)
File ".../env/lib/python3.7/site-packages/django/views/generic/base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File ".../env/lib/python3.7/site-packages/django/utils/decorators.py", line 43, in _wrapper
return bound_method(*args, **kwargs)
File ".../env/lib/python3.7/site-packages/django/views/decorators/debug.py", line 76, in sensitive_post_parameters_wrapper
return view(request, *args, **kwargs)
File ".../env/lib/python3.7/site-packages/django/utils/decorators.py", line 43, in _wrapper
return bound_method(*args, **kwargs)
File ".../env/lib/python3.7/site-packages/django/utils/decorators.py", line 130, in _wrapped_view
response = view_func(request, *args, **kwargs)
File ".../env/lib/python3.7/site-packages/django/utils/decorators.py", line 43, in _wrapper
return bound_method(*args, **kwargs)
File ".../env/lib/python3.7/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func
response = view_func(request, *args, **kwargs)
File ".../env/lib/python3.7/site-packages/django/contrib/auth/views.py", line 63, in dispatch
return super().dispatch(request, *args, **kwargs)
File ".../env/lib/python3.7/site-packages/django/views/generic/base.py", line 97, in dispatch
return handler(request, *args, **kwargs)
File ".../env/lib/python3.7/site-packages/django/views/generic/edit.py", line 141, in post
if form.is_valid():
File ".../env/lib/python3.7/site-packages/django/forms/forms.py", line 180, in is_valid
return self.is_bound and not self.errors
File ".../env/lib/python3.7/site-packages/django/forms/forms.py", line 175, in errors
self.full_clean()
File ".../env/lib/python3.7/site-packages/django/forms/forms.py", line 377, in full_clean
self._clean_form()
File ".../env/lib/python3.7/site-packages/django/forms/forms.py", line 404, in _clean_form
cleaned_data = self.clean()
File ".../env/lib/python3.7/site-packages/django/contrib/auth/forms.py", line 214, in clean
self.user_cache = authenticate(self.request, username=username, password=password)
File ".../env/lib/python3.7/site-packages/django/contrib/auth/__init__.py", line 74, in authenticate
user = backend.authenticate(request, )
File ".../users/backends.py", line 12, in authenticate
username = request.data.get("username")
AttributeError: 'WSGIRequest' object has no attribute 'data'

我通过添加到authenticate方法暂时解决了这个问题;

def authenticate(request=None, **credentials):
"""
If the given credentials are valid, return a User object.
"""
for backend, backend_path in _get_backends(return_tuples=True):
try:
inspect.getcallargs(backend.authenticate, request, **credentials)
except TypeError:
# This backend doesn't accept these credentials as arguments. Try the next one.
continue
try:
user = backend.authenticate(request, **credentials)
except PermissionDenied:
# This backend says to stop in our tracks - this user should not be allowed in at all.
break
if user is None:
continue
# Annotate the user object with the path of the backend.
user.backend = backend_path
return user
# The credentials supplied are invalid to all backends, fire signal
user_login_failed.send(sender=__name__, credentials=_clean_credentials(credentials), request=request)

所以现在user = backend.authenticate(request, **credentials)方法获取凭据,一旦登录到管理面板,我就可以删除这一行,但理想情况下我想知道它为什么仍然这样做。

最新更新