Kakar
Kakar

Reputation: 5599

Authenticate users with both username and email

I have extendted the UserCreationForm with email and other fields, so that I could authenticate a user with both its username and email.

forms.py:

class UserCreationForm(UserCreationForm):

    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'username', 'email',)

views.py:

def auth_view(request):
    username = request.POST.get('username','')
    password = request.POST.get('password','')
    user = auth.authenticate(username=username, password=password)

    if user is not None:
        auth.login(request, user)
        return HttpResponseRedirect('/')
    elif:
        user = auth.authenticate(email=username, password=password)
        if user is not None:
            auth.login(request, user)
            return HttpResponseRedirect('/')
    else:
        return HttpResponseRedirect('/accounts/invalid_login')

html:

<form action="/accounts/auth/" method="post">
    {%csrf_token%}

    <label for="name">Email or Username:</label>
    <input type="text" name="name" id="name" value="">
    <label for="password">Password:</label>
    <input type="password" name="password" id="password" value="">

    <input type="submit" value="LOGIN">
</form>

In the views I tried giving both the username and email as input from the form as name, and check to see if username and password authenticate. If not then check whether email and password authenticate. But its not working. How do I solve this problem? Please kindly help me. Thank you.

Upvotes: 1

Views: 2695

Answers (1)

warath-coder
warath-coder

Reputation: 2122

You need to create an authentication backend: here is mine:

class EmailAuthBackend(ModelBackend):
    """
    Email Authentication Backend

    Allows a user to sign in using an email/password pair, then check
    a username/password pair if email failed
    """

    def authenticate(self, username=None, password=None):
        """ Authenticate a user based on email address as the user name. """
        try:
            user = User.objects.get(email=username)
            if user.check_password(password):
                return user
        except User.DoesNotExist:
            try:
                user = User.objects.get(username=username)
                if user.check_password(password):
                    return user
            except User.DoesNotExist:
                return None

    def get_user(self, user_id):
        """ Get a User object from the user_id. """
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

Then in your settings:

AUTHENTICATION_BACKENDS = ('MyApp.backends.EmailAuthBackend',)

then create a custom view the uses the authenticate function.

Upvotes: 4

Related Questions