Django自定义身份验证后端不起作用

时间:2018-08-16 06:24:34

标签: python django

我希望我的Django项目通过用户的电子邮件(而不是用户名)对用户进行身份验证。我遵循了this suggestion,但不起作用。

这是我的EmailBackend

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

class EmailBackend(ModelBackend):
    def authenticate(self, username=None, password=None, **kwars):
        UserModel = get_user_model()
        try:
            user = UserModel.objects.get(email=username)
        except UserModel.DoesNotExist:
            return None
        else:
            if user.check_password(password):
                return user

        return None

我已将AUTHENTICATION_BACKENDS = ['GeneralApp.utils.EmailBackend']添加到 settings.py ,并且在注释后,我可以使用用户名登录,而在取消注释时,就无法登录。我已经发现GeneralApp.utils.EmailBackend.authenticate()的代码从未执行过,但是我知道Django可以找到该类,因为我故意将其拼写错误并且出现错误,并且当我纠正错字时,不会引发任何异常。我也知道默认身份验证后端已被有效覆盖,因为我都无法使用用户名登录。我拥有相同的解决方案,可以在另一个项目中完美地工作,所以我无法理解为什么在将AUTHENTICATION_BACKENDS设置为完美的类的情况下,从不执行自定义身份验证代码。

3 个答案:

答案 0 :(得分:10)

好的,我之前在Django 2.0.5上已经尝试过了,但是它停止在Django 2.1上工作。我研究了here,发现自定义身份验证后端类现在希望在方法 authenticate 中使用参数 request 。因此,Django 2.1的最终代码是:

class EmailBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwars):
        UserModel = get_user_model()
        try:
            user = UserModel.objects.get(email=username)
        except UserModel.DoesNotExist:
            return None
        else:
            if user.check_password(password):
                return user

        return None

答案 1 :(得分:1)

我想this可以为您提供帮助。 从助手类继承并创建Custom用户是比编写自己的自定义后端更好的方法。

答案 2 :(得分:1)

在Django 3.x中工作

自定义身份验证文件如下:

var map = {
  prop0: "p0",
  prop1: "p1",
  prop2: "p2"
}

var obj = {
  prop0: "value0",
  prop1: [{
      prop2: "value2"
    },
    {
      prop2: "value3"
    },
    {
      prop2: "value4"
    }
  ]
}
const newObj = {};
for (let key in obj) {
  if (Array.isArray(obj[key])) {
    newObj[map[key]] = obj[key].map(x => {
      const arrKey = Object.keys(x)[0];
      return {
        [map[arrKey]]: x[arrKey]
      }
    })
  } else {
    newObj[map[key]] = obj[key]
  }
}
console.log(JSON.stringify(newObj))

,然后在settings.py中,我们需要输入:

from django.contrib.auth import get_user_model


User = get_user_model()


class EmailAuthBackend(object):
    """It provides the functionality to slide down to email to login,
    instead of just username"""
    def authenticate(self,request,username=None,password=None):
        try:
            user = User.objects.get(email=username)
            if user.check_password(password):
                return user 
            return None
        except User.DoesNotExist:
            return None

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