Пользовательская аутентификация в django не работает - PullRequest
0 голосов
/ 12 февраля 2019

Я новичок в django, и я хотел аутентифицировать пользователя на email или username с password, поэтому я написал пользовательскую аутентификацию, как показано в документации, но она, кажется, не вызывается, и я понятия не имею,что мне делать?

settings.py

AUTHENTICATION_BACKENDS = ('accounts.backend.AuthBackend',)

views.py

def login(request):
    if request.method == 'POST':
        username_or_email = request.POST['username']
        password = request.POST['password']
        user = authenticate(username=username_or_email, password=password)
        print(user)
        if user is not None:
            return reverse('task:home')
        else:
            messages.error(request, "Username or password is invalid")
            return render(request, 'accounts/login.html')
    else:
         return render(request, 'accounts/login.html')

backend.py

from django.contrib.auth.models import User
from django.db.models import Q


class AuthBackend(object):
    supports_object_permissions = True
    supports_anonymous_user = False
    supports_inactive_user = False

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

    def authenticate(self, username, password):
        print('inside custom auth')
        try:
            user = User.objects.get(
                Q(username=username) | Q(email=username) )
            print(user)
        except User.DoesNotExist:
            return None
        print(user)
        if user.check_password(password):
             return user
        else:
            return None

Я написал эти print операторы в своем классе, чтобы проверить, вызываются ли они и записываются в консоли.Однако они не печатаются, и оператор print в views.py печатает None

Ответы [ 2 ]

0 голосов
/ 01 июня 2019
import sys
from django.contrib.auth import get_user_model

from accounts.models import Token

User = get_user_model()


class PasswordlessAuthenticationBackend:

    def authenticate(self, uid=None):
        print('uuuuuuuuu')
        print('uid', uid, file=sys.stderr)
        if not Token.objects.filter(uid=uid).exists():
            print('no token found', file=sys.stderr)
            return None
        token = Token.objects.get(uid=uid)
        print('got token', file=sys.stderr)
        try:
            user = User.objects.get(email=token.email)
            print('got user', file=sys.stderr)
            return user
        except User.DoesNotExist:
            print('new user', file=sys.stderr)
            return User.objects.create(email=token.email)

    def get_user(self, email):
        try:
            return User.objects.get(email=email)
        except User.DoesNotExist:
            return None
0 голосов
/ 12 февраля 2019

Вам необходимо extend ModelBackend из django.contrib.auth.backends

from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend

User = get_user_model()

class AuthBackend(ModelBackend):
    supports_object_permissions = True
    supports_anonymous_user = False
    supports_inactive_user = False

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

    def authenticate(self, request, username=None, password=None):
        print('inside custom auth')
        try:
            user = User.objects.get(
                Q(username=username) | Q(email=username) )
            print(user)
        except User.DoesNotExist:
            return None
        print(user)
        if user.check_password(password):
             return user
        else:
            return None

А также в settings.py не забудьте добавить свою собственную аутентификацию бэкэнда

AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend',
    'accounts.backend.AuthBackend'
]

Другое возможное решение

Из вашего кода я вижу, что вы хотите, чтобы ваш email рассматривал как user_name модели User.Вы можете легко изменить модель Django's AbstructUser, как показано ниже:

from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
      # your necessary additional fields 
       USERNAME_FIELD = 'email'  # add this line 

Теперь email поле будет считаться полем user_name.Нет необходимости добавлять пользовательские authentication-backend

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...