Sau*_*rma 8 django django-authentication django-users
我的自定义用户模型:
class MyUser(AbstractBaseUser):
username = models.CharField(unique=True,max_length=30)
email = models.EmailField(unique=True,max_length=75)
is_staff = models.IntegerField(default=False)
is_active = models.IntegerField(default=False)
date_joined = models.DateTimeField(default=None)
# Use default usermanager
objects = UserManager()
USERNAME_FIELD = 'email'
Run Code Online (Sandbox Code Playgroud)
有没有办法指定多个USERNAME_FIELD?有类似的东西['email','username'],用户可以通过电子邮件和用户名登录?
Ala*_*air 10
该USERNAME_FIELD设置不支持列表.您可以创建一个自定义身份验证后端,尝试在"电子邮件"或"用户名"字段中查找用户.
from django.db.models import Q
from django.contrib.auth import get_user_model
MyUser = get_user_model()
class UsernameOrEmailBackend(object):
def authenticate(self, username=None, password=None, **kwargs):
try:
# Try to fetch the user by searching the username or email field
user = MyUser.objects.get(Q(username=username)|Q(email=username))
if user.check_password(password):
return user
except MyUser.DoesNotExist:
# Run the default password hasher once to reduce the timing
# difference between an existing and a non-existing user (#20760).
MyUser().set_password(password)
Run Code Online (Sandbox Code Playgroud)
然后,在您的身份验证后端settings.py设置AUTHENTICATION_BACKENDS中:
AUTHENTICATION_BACKENDS = ('path.to.UsernameOrEmailBackend,)\
Run Code Online (Sandbox Code Playgroud)
请注意,此解决方案并不完美.例如,密码重置仅适用于您USERNAME_FIELD设置中指定的字段.
我们可以通过实现自己的电子邮件身份验证后端来实现.
您可以执行以下操作:
步骤1在设置中替换自定义用户模型:
由于我们不会使用Django的默认User模型进行身份验证,因此我们需要定义自定义MyUser模型settings.py.指定MyUser为AUTH_USER_MODEL项目设置中的.
AUTH_USER_MODEL = 'myapp.MyUser'
Run Code Online (Sandbox Code Playgroud)
步骤2编写自定义身份验证后端的逻辑:
要编写我们自己的身份验证后端,我们需要实现至少两个方法,即get_user(user_id)和authenticate(**credentials).
from django.contrib.auth import get_user_model
from django.contrib.auth.models import check_password
class MyEmailBackend(object):
"""
Custom Email Backend to perform authentication via email
"""
def authenticate(self, username=None, password=None):
my_user_model = get_user_model()
try:
user = my_user_model.objects.get(email=username)
if user.check_password(password):
return user # return user on valid credentials
except my_user_model.DoesNotExist:
return None # return None if custom user model does not exist
except:
return None # return None in case of other exceptions
def get_user(self, user_id):
my_user_model = get_user_model()
try:
return my_user_model.objects.get(pk=user_id)
except my_user_model.DoesNotExist:
return None
Run Code Online (Sandbox Code Playgroud)
步骤3在设置中指定自定义身份验证后端:
编写自定义身份验证后端后,在AUTHENTICATION_BACKENDS设置中指定此身份验证后端.
AUTHENTICATION_BACKENDS包含要使用的身份验证后端列表.Django尝试在其所有身份验证后端进行身份验证.如果第一个身份验证方法失败,Django会尝试第二个身份验证方法,依此类推,直到尝试了所有后端.
AUTHENTICATION_BACKENDS = (
'my_app.backends.MyEmailBackend', # our custom authentication backend
'django.contrib.auth.backends.ModelBackend' # fallback to default authentication backend if first fails
)
Run Code Online (Sandbox Code Playgroud)
如果身份验证MyEmailBackend失败,即用户无法通过身份验证email,那么我们将使用Django的默认身份验证ModelBackend,该身份验证将尝试通过模型username字段进行身份验证MyUser.
| 归档时间: |
|
| 查看次数: |
6832 次 |
| 最近记录: |