使用自定义模型的Django身份验证

时间:2019-11-19 07:39:43

标签: django authentication hash

我使用mysql表进行自定义登录身份验证,同时登录后如何在backends.py中将散列密码与纯密码进行比较(使用普通密码可以正常工作)?

class MyBackEnd(object):
    def authenticate(self, request, email=None, password=None):
        existing_user = RegAuth.objects.get(email=email,password=password)
        if not existing_user:
            # Checking the user Regauth Custom DB.
            user_data = RegAuth.objects.get(email=email,password=password)
            if email == user_data.email:
                user = RegAuth.objects.create_user(email=email, password=password)
                user.save()
                return user
            else:
                return None
        else:
            return existing_user

    def get_user(self, email):
        try:
            return RegAuth.objects.get(email=email)
        except Exception as e:
            return False

登录视图

    def logauth(request):
    if request.method == "POST":
        email = request.POST['username']
        password = request.POST['password']

        user = authenticate(request, email=email, password=password)

        if user is not None:
            messages.error(request, 'if part : user is not  None')
            login(request, user)
            return redirect('emp')
        else:
            messages.error(request, 'else part : user is None')
            return redirect('login_url')
    else:
        messages.error(request, 'Please provide valid credentials')
        return render(request, 'registration/login.html')

1 个答案:

答案 0 :(得分:0)

是否有某些特殊原因需要脱离Django的默认身份验证后端?我发现您的身份验证方法至少存在一些问题;

class MyBackEnd(object):
    def authenticate(self, request, email=None, password=None):
        # 1. password should not be used to retrieve a user, a pk should suffice
        existing_user = RegAuth.objects.get(email=email,password=password)
        if not existing_user:
            # Checking the user Regauth Custom DB.
            # 2. if the query before didn't yield results, why would it atp?
            user_data = RegAuth.objects.get(email=email,password=password)
            if email == user_data.email:
                # 3. I'm not sure what flow validates this path, could you explain?
                user = RegAuth.objects.create_user(email=email, password=password)
                user.save()
                return user
            else:
                return None
        else:
            return existing_user

作为参考,这是Django的默认身份验证后端方法(请注意使用else / else语法):

 def authenticate(self, request, username=None, password=None, **kwargs):
        if username is None:
            username = kwargs.get(UserModel.USERNAME_FIELD)
        try:
            user = UserModel._default_manager.get_by_natural_key(username)
        except UserModel.DoesNotExist:
            # Run the default password hasher once to reduce the timing
            # difference between an existing and a non-existing user (#20760).
            UserModel().set_password(password)
        else:
            if user.check_password(password) and self.user_can_authenticate(user):
                return user

它;

  1. 然后尝试检索用户;
  2. 检查密码,然后
  3. 然后验证用户的状态; <​​/ li>
  4. 将用户对象返回给调用者(成功认证),或者
  5. 不将用户返回到呼叫者。 (身份验证失败)

或者(找不到用户);

  1. 实例化用户对象,并且
  2. 然后使用set_password(会对其进行散列)设置密码;
  3. 不将用户返回到呼叫者。 (身份验证失败)

此备用流对set_password的使用旨在减轻一些定时攻击,请参阅:https://code.djangoproject.com/ticket/20760

如果您要注册新用户,重设用户密码或除验证之外的任何其他方法,则authenticate方法为 not 正确的位置。

我知道这不是您所提问题的答案,但我希望它能帮助您和其他人了解身份验证流程,并对脱离身份验证流程至关重要。