Authenticate user using email and password

后端 未结 3 1900
我寻月下人不归
我寻月下人不归 2021-02-09 23:36

I have a form that only allow users to login via username . I decided to only allow user to login via email instead of username.

First, this is not a duplication of any

相关标签:
3条回答
  • 2021-02-09 23:57

    Looks like you are testing against 2 different fields. You look for the user against email

    if User.objects.filter(email=user).exists():
    

    but then validate against username

    user = authenticate(username=user, password=password)
    

    If you are using the email address the auth line should be

    user = authenticate(email=user, password=password)
    
    0 讨论(0)
  • 2021-02-10 00:07

    You can also write a custom backend:

    # yourapp.backends.py    
    from django.contrib.auth.models import User
    
    
    class EmailOrUsernameModelBackend(object):
        """ Authenticate user by username or email """
        def authenticate(self, username=None, password=None):
            if '@' in username:
                kwargs = {'email': username}
            else:
                kwargs = {'username': username}
            try:
    
                user = User.objects.get(**kwargs)
                if user.check_password(password):
                    return user
                else:
                    return None
            except User.DoesNotExist:
                return None
    
        def get_user(self, user_id=None):
            try:
                return User.objects.get(pk=user_id)
            except User.DoesNotExist:
                return None
    

    Now add your backend to settings.py:

    AUTHENTICATION_BACKENDS = (
        'yourapp.backends.EmailOrUsernameModelBackend',
        'django.contrib.auth.backends.ModelBackend',
    )
    
    0 讨论(0)
  • 2021-02-10 00:14

    As dougis pointed out you are trying to authenticate the user using email, But authenticate function authenticates user based on username and password. So here is the trick to authenticate the user using email (complete working form):

    from django.db.models import Q
    from django.core.exceptions import ObjectDoesNotExist
    from django.contrib.auth.models import User
    from django import forms
    from django.contrib.auth import authenticate
    
    class LoginForm(forms.Form):
        email = forms.CharField()
        password = forms.CharField(
            widget=forms.PasswordInput(render_value=False)
            )
    
        def clean(self):
            user = self.authenticate_via_email()
            if not user:
                raise forms.ValidationError("Sorry, that login was invalid. Please try again.")
            else:
                self.user = user
            return self.cleaned_data
    
        def authenticate_user(self):
            return authenticate(
                username=self.user.username,
                password=self.cleaned_data['password'])
    
        def authenticate_via_email(self):
            """
                Authenticate user using email.
                Returns user object if authenticated else None
            """
            email = self.cleaned_data['email']
            if email:
                try:
                    user = User.objects.get(email__iexact=email)
                    if user.check_password(self.cleaned_data['password']):
                        return user
                except ObjectDoesNotExist:
                    pass
            return None
    

    views.py

    def LoginRequest(request):
        form = LoginForm(request.POST or None)    
        if request.method == 'POST' and form.is_valid():
            user = form.authenticate_user()
            login(request, user)
            return HttpResponseRedirect(reverse('Hello'))
    
        return render(request, 'login.html',{'form': form})
    
    0 讨论(0)
提交回复
热议问题