我正在使用Django rest框架与djoser。
我想通过电子邮件或用户名在Djoser(JWT)登录。你能给我一个解决办法吗?(我使用自定义用户模型)
请回答。
My Simple Method to do Job Done:
我用:
Django==3.2.9
djangorestframework==3.12.4
djangorestframework-simplejwt==5.0.0
我有我的自定义用户模型,可以根据我的需求进行更多的自定义
在我的自定义User模型中,我将Email地址定义为默认用户名字段。如下所示:USERNAME_FIELD = 'email'
我的设置:
in setting.py file
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
...
}
in Urls.py file
urlpatterns = [
path('token', MyObtainTokenPairView.as_view(), name='token_obtain_pair'),
# in my case this token route is the login route
]
现在我有我的自定义登录视图命名为MyObtainTokenPairView,它有以下代码:
from .serializers import MyTokenObtainPairSerializer
from rest_framework.permissions import AllowAny
from rest_framework_simplejwt.views import TokenObtainPairView
class MyObtainTokenPairView(TokenObtainPairView):
permission_classes = [AllowAny]
serializer_class = MyTokenObtainPairSerializer
为了序列化的目的,我使用我的默认序列化类,它覆盖了TokenObtainPairSerializerrest_framework_simplejwt序列化器的类方法如下:
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework import exceptions
from users.models import Users
from utilities.dataValidation import validateEmail
class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
@classmethod
def get_token(cls, user):
token = super().get_token(user)
token['user_name'] = user.user_name
token['email'] = user.email
return token
def validate(self, attrs):
userName = attrs.get("email")
password = attrs.get("password")
# print("attrs values: ", attrs)
if validateEmail(userName) is False:
try:
user = Users.objects.get(user_name=userName)
if user.check_password(password):
attrs['email'] = user.email
"""
In my case, I used the Email address as the default Username
field in my custom User model. so that I get the user email
from the Users model and set it to the attrs field. You can
be modified as your setting and your requirement
"""
except Users.DoesNotExist:
raise exceptions.AuthenticationFailed(
'No such user with provided credentials'.title())
data = super().validate(attrs)
return data
检查邮件是否有效,我使用了如下一个函数:
from django.core.validators import validate_email
from django.core.exceptions import ValidationError
def validateEmail(email):
try:
validate_email(email)
return True
except ValidationError:
return False
所有这些工作都完成了,我可以使用电子邮件或用户的UserName登录用户。