允许在django项目中登录电子邮件和用户名

时间:2017-07-07 14:13:15

标签: python django

我正在为一所学校创建一个django项目,主要有三种用户 - 家长,老师和学生。对于家长和老师,我希望他们使用电子邮件登录(他们目前正在使用遗留系统的电子邮件登录)。

然而,对于学生,我希望他们使用传统的用户名方法登录(因为年幼的孩子没有电子邮件)。这是可以在Django中做到还是只允许一个用户身份验证模型?

5 个答案:

答案 0 :(得分:2)

您可以创建单独的onload,仅用于通过电子邮件进行记录,并将其添加到设置中的AuthenticationEmailBackend。通过这种方式,如果以前的AUTHENTICATION_BACKENDS身份验证失败,则会使用不同的AUTHENTICATION_BACKENDS作为备选方案。

应用/ auth.py

AUTHENTICATION_BACKENDS

<强> settings.py

from django.contrib.auth import get_user_model
from django.contrib.auth.models import User


class AuthenticationEmailBackend(object):
    def authenticate(self, username=None, password=None, **kwargs):
        UserModel = get_user_model()
        try:
            user = UserModel.objects.get(email=username)
        except UserModel.DoesNotExist:
            return None
        else:
            if getattr(user, 'is_active', False) and user.check_password(password):
                return user
        return None

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

如果您在列表中保留默认AUTHENTICATION_BACKENDS = ( "django.contrib.auth.backends.ModelBackend", ... "app.auth.AuthenticationEmailBackend", ) ,则用户可以通过用户名或电子邮件登录。

答案 1 :(得分:2)

对于Django 3.0:

# myapp/backends.py

from django.contrib.auth.backends import BaseBackend

from .models import MyUser


class EmailAuthenticationBackend(BaseBackend):

def authenticate(self, request, **kwargs):
    email = kwargs['username'].lower()  # If you made email case insensitive add lower()
    password = kwargs['password']
    try:
        my_user = MyUser.objects.get(email=email)
    except MyUser.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 MyUser.objects.get(pk=user_id)
    except MyUser.DoesNotExist:
        return None

这适用于Django 2.0和以前的版本:

# myapp/backends.py

from django.contrib.auth.backends import ModelBackend

from .models import MyUser


class EmailAuthenticationBackend(ModelBackend):

    def authenticate(self, request, **kwargs):
        email = kwargs['username']
        password = kwargs['password']
        try:
            my_user = MyUser.objects.get(email=email)
        except MyUser.DoesNotExist:
            return None
        else:
            if my_user.is_active and my_user.check_password(password):
                return my_user
        return None

(不确定扩展ModelBackend是否是一个好主意,您可以创建自己的类)

然后,对于两个版本:

# settings.py

AUTHENTICATION_BACKENDS = [
    "django.contrib.auth.backends.ModelBackend",
    "myapp.backends.EmailAuthenticationBackend",
]

答案 2 :(得分:1)

一个简单的后端,允许您使用电子邮件地址或用户名登录。

它应与另一个后端结合使用以检查权限:

settings.py:

AUTHENTICATION_BACKENDS = (
    'myproject.accounts.backends.EmailOrUsernameModelBackend',
    'django.contrib.auth.backends.ModelBackend' )

帐户/后端。py:

from django.conf import settings
from django.contrib.auth.models import User

class EmailOrUsernameModelBackend(object):
    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
        except User.DoesNotExist:
            return None

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

,并且不区分大小写:

class EmailOrUsernameModelBackend(object):
    def authenticate(self, username=None, password=None):
        # user_model = get_user_model()
        if '@' in username:
            # kwargs = {'email': username}
            field = 'email'
        else:
            # kwargs = {'username': username}
            field = 'username'
        try:

            case_insensitive_username_field = '{}__iexact'.format(field)
            user = User._default_manager.get(**{case_insensitive_username_field: username})

            # user = User.objects.get(**kwargs)
            if user.check_password(password):
                return user
        except User.DoesNotExist:
            return None

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

答案 3 :(得分:1)

Django 1.11的身份验证方法中,需要

似乎 request 参数:

def authenticate(self, request, username=None, password=None)

根据Django documentation中的说法。

答案 4 :(得分:0)

在models.py

class UserDet(models.Model):
       email = models.EmailField(max_length=20)
 
       userName = models.CharField(max_length=20) 

在views.py

def user_login(request):
    response_data={}
    if request.session.has_key('login_id'):  #If user already logedin send to dashboard else check userid and password
        return render(request, '/dashboard.html')
    else:
        if request.method == 'POST':  # If request method is post then only process request
            #print('here in login')
            try:

                username = request.POST.get('username')
                password = request.POST.get('pass')

                if '@' in username: #check for email
                    try:
                         
                        for u in UserDet.objects.filter(email=username):
                            #username=u['userName']
                            
                            username=u.userName
                    except:
                        response_data['code']=1000
                        response_data['status']='fail'
                        return HttpResponse(json.dumps(response_data), content_type="application/json")

                if not request.POST.get('rememberme', None):  # check user select the remember me or not if yes then create session that expire after long time
                    #print('seeing it 0')
                    request.session.set_expiry(0)
                 
                
                user = authenticate(username=username, password=password) # Check user exist or not
                
                if user:  #if user exist then
                    if user.is_active: #check user is active or not if active then successfully loged in else send error
                        login(request,user)
                        
                        update_last_login(None, user)
                        request.session['login_id'] = user.id
                        response_data['code']=800
                        response_data['status']='success'
                        return HttpResponse(json.dumps(response_data), content_type="application/json")
                        #return render(request, '/dashboard.html')
                    else:
                        response_data['code']=900  #Error for User is not active
                        response_data['status']='fail'
                        return HttpResponse(json.dumps(response_data), content_type="application/json")
                        #return HttpResponse("Your account was inactive.")
                else: #Error or Invalid username or password
                    #print("Someone tried to login and failed.")
                    #print("They used username: {} and password: {}".format(username,password))
                    response_data['code']=1000
                    response_data['status']='fail'
                    return HttpResponse(json.dumps(response_data), content_type="application/json")
            
            except:
                response_data['code']=1001
                response_data['status']='fail'
                return HttpResponse(json.dumps(response_data), content_type="application/json")
        else: #Return to index
                return redirect('/', {})