繁体   English   中英

验证()对于 django 无法正常工作

[英]authenticate() not working properly for django

基本上我到目前为止所做的是创建一个注册页面,用户在其中输入用户名和密码,然后将该密码存储为哈希密码(md5 hasher)。 我遇到的问题是登录。用户输入他们的用户名和密码,然后使用 django 中的 authenticate() 方法对密码进行身份验证。 问题是 authenticate() 返回 None 而不是匹配数据库中的用户和密码。 我不知道这是否会影响任何事情,但我正在使用 PostgreSQL。

模型.py

class MyAccountManager(BaseUserManager):
    def create_user(self, email,username,first_name,password= None):
        if not email:
            raise ValueError('User must have an email address')
        if not username:
            raise ValueError('User must have a username')
        if not first_name:
            raise ValueError('User must have a first name')
        user= self.model(
            email=self.normalize_email(email),
            username= username,
            first_name= first_name
        )
        user.set_password(password)
        user.save(using=self._db)
        return user
    
    def create_superuser(self, email, username, first_name, password):
        user= self.create_user(
            email= self.normalize_email(email),
            username=username,
            first_name= first_name,
            password= password,
        )
        user.is_admin= True
        user.is_staff= True
        user.is_superuser= True
        user.save(using=self._db)
        return user
    
class User(AbstractBaseUser, models.Model):
    email = models.EmailField(verbose_name='email', max_length=60, unique=True)
    username = models.CharField(max_length=30, unique=True)
    date_joined = models.DateTimeField(auto_now_add=True, verbose_name='date joined')
    last_login = models.DateTimeField(verbose_name='last login', auto_now=True)
    is_admin = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

    USERNAME_FIELD= 'username'
    REQUIRED_FIELDS= ['email','first_name']
    
    objects= MyAccountManager()
    def __str__(self):
        return self.email

    def has_perm(self, perm, obj=None):
        return self.is_admin

    def has_module_perms(self, app_label):
        return True

forms.py

class LoginForm(forms.Form):
    username = forms.CharField(initial='' ,label='Username:',max_length=30)
    password = forms.CharField(max_length=20, widget=forms.PasswordInput())
    class Meta:
        model = User
        fields = ('username', 'password')
    def clean(self):
        cleaned_data = super(LoginForm, self).clean()
        confirm_password = cleaned_data.get('password')



class SignUpForm(forms.ModelForm):
    first_name = forms.CharField(required= True,initial='',max_length=20)
    last_name = forms.CharField(required=True,max_length=30, initial='')
    username = forms.CharField(max_length=30,initial='', required=True)
    password = forms.CharField(max_length= 20, initial='', widget = forms.PasswordInput())
    password2= forms.CharField(max_length=20, initial='',widget = forms.PasswordInput())
    email = forms.EmailField(max_length=60, initial='',)

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

    def clean(self):
        cleaned_data = super(SignUpForm,self).clean()
        password = cleaned_data.get('password')
        confirm_password = cleaned_data.get('password2')
        if(password != confirm_password):
            raise forms.ValidationError(
                'Password and Confirm Password do not match.'
            )

视图.py

def signin_and_signup(request):

    if request.method == 'POST':
        logout(request)
        sign_in = LoginForm(request.POST)
        signup = SignUpForm(request.POST)
        if 'sign-in-name' in request.POST:
            if sign_in.is_valid():
                username = request.POST.get('username')
                password= request.POST.get('password')
                user = authenticate(username= username, password= password)
                if user:
                    return HttpResponse('success')
                else:
                    return HttpResponse('fail')
        elif 'sign-up-input-name' in request.POST:
            if(signup.is_valid()):
                user = signup.save(commit=False)
                nonHashed = signup.cleaned_data['password']
                varhash =  make_password(nonHashed, None, 'md5')
                user.set_password(varhash)
                user.save()

            else:
                print("Ran3<------------")
                signup = SignUpForm()
    else:
        sign_in = LoginForm()
        signup = SignUpForm()
    context = {'signin':sign_in, 'signup':signup}
    return render(request, 'home.html', context)

如果你有相同的属性,你为什么要替换 django 提供的用户 model? 如果您想为用户扩展或添加新属性,例如许可证号、头像、position,则会执行此操作。

无论如何,您的 authenticate() 可能不起作用,因为您尚未在 settings.py 中注册新的 model。

AUTH_USER_MODEL = 'name_of_the_app.User'

我建议你看一下官方文档https://docs.djangoproject.com/en/3.1/topics/auth/customizing/

Antoher 可能是您的身份验证后端:

尝试:

设置.py

AUTHENTICATION_BACKENDS = [
    'name_of_the_app.admin.LoginBackend',
]

你想要的地方,例如 admin.py

from django.contrib.auth.backends import ModelBackend, UserModel
from django.db.models import Q


class LoginBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        try:  # to allow authentication through phone number or any other field, modify the below statement
            user = UserModel.objects.get(Q(username__iexact=username) | Q(email__iexact=username))
        except UserModel.DoesNotExist:
            UserModel().set_password(password)
        except MultipleObjectsReturned:
            return models.User.objects.filter(email=username).order_by('id').first()
        else:
            if user.check_password(password) and self.user_can_authenticate(user):
                return user
    
    def get_user(self, user_id):
        try:
            user = UserModel.objects.get(pk=user_id)
        except UserModel.DoesNotExist:
            return None

        return user if self.user_can_authenticate(user) else None

如您所见,您也可以使用 email 登录

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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