简体   繁体   中英

Django User Login via Email & Password

I just completed the Django tutorial and want to create a website that requires users to sign in with an email address and password. This is completely separate from Django's awesome built-in Admin site (only one or two special people should have access to the Admin).

My questions are:

  1. Should I create a separate database table to store user credentials, info, etc? Or should I use an existing Django table?

  2. As mentioned, users should sign in with an email address. Will this be a problem for Django?

Other best-practices would be much appreciated. Thank you.

You won't need a separate table for user logins. Just leverage the Auth framework Allowing users to sign in with their email address is pretty simple, but there are a few different ways to approach the subject. You'll want to start with: https://docs.djangoproject.com/en/1.7/topics/auth/customizing/

First what is middleware It's a light, low-level “plugin” system for globally altering Django's input or output.

And you can read here how to activating-middleware

Creating email backend middleware will help you to achieve authenticate a user based on email address as the user name

    def authenticate(self, username=None, password=None):
        try:
            user = User.objects.get(email=username)
            if user.check_password(password):
                return user
        except User.DoesNotExist:
            return None 

Brandon is right, The simplest way to do this is to customize the backend instead of the Django default Let's do this In your settings.py:

AUTHENTICATION_BACKENDS = ('accounts.backend.EmailOrUsernameModelBackend')

Then in the accounts/backend.py:

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

User = get_user_model()


class EmailOrUsernameModelBackend(_ModelBackend):
    """ 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 you can login with your username or email Have fun

add this to settings.py

AUTHENTICATION_BACKENDS = ['accounts.backends.EmailOrUsernameAuthenticationBackend']

and add this to accounts/backends.py

from django.contrib.auth.backends import BaseBackend
from django.contrib.auth.models import User


class EmailOrUsernameAuthenticationBackend(BaseBackend):

    def authenticate(self, request, **kwargs):
        username = kwargs['username']
        password = kwargs['password']
        try:
            if '@' in username:
                my_user = User.objects.get(email=username)
            else:
                my_user = User.objects.get(username=username)

        except User.DoesNotExist:
            return None
        else:
            if my_user.is_active and my_user.check_password(password):
                return my_user
        return None

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM