DJANGO + JWT令牌认证

时间:2020-07-03 16:21:35

标签: django django-rest-framework jwt jwt-auth django-rest-framework-jwt

所以我试图为我的Android应用程序构建一个后端。我正在尝试应用适用于JWT令牌的登录过程

这就是我所做的:

  1. 我已经制作了一个自定义的用户模型。
  2. 自定义我的超级用户以使用电话号码和密码,而不是用户名和密码
  3. 我已经成功创建了超级用户并将其存储在数据库中(使用postgreSQL)。
  4. 我还自定义了令牌声明和响应,如我的LoginSerializer类的 serializers.py 所示。

但是,我做完之后遇到了一些问题:

  1. 现在,自定义用户模型后,即使我成功创建了超级用户,也无法使用新的定制用户模型登录Django管理。
  2. 即使使用刚刚创建的成功超级用户帐户对令牌声明进行了自定义,我仍然无法获得令牌。

以下是一些错误消息:

enter image description here

enter image description here

以下是一些附加的文件:

models.py

from django.db import models   
from django.contrib.auth.models import AbstractBaseUser,BaseUserManager
from django.utils.translation import ugettext_lazy as _
from phone_field import PhoneField

class RegisterUserManager(BaseUserManager):

    def create_user(self, phone_number,password):

        if not phone_number:
            raise ValueError('The phone number must be set')

        user = self.model(
            phone_number=phone_number,
            password = password,)

        user.save(using = self._db)
       
        return user
        
    def create_superuser(self,phone_number,password, **extra_fields):

        user = self.create_user(
            phone_number,
            password = password
        )

        user.is_admin =  True
        user.save(using= self._db)

        return user


class RegisterUser(AbstractBaseUser):
    first_name = models.CharField(name = 'first_name',max_length=255,default = '')
    last_name = models.CharField(name='last_name', max_length=255,default = '')
    email = models.EmailField(name='email', max_length = 255)
    phone_number = PhoneField(name='phone_number',unique=True)
    birthday = models.DateField(name ='birthday',null= True)
    nickname = models.CharField(max_length=100,name = 'nickname')
    is_active = models.BooleanField(default = True)
    is_admin = models.BooleanField(default= False)
    last_login = models.DateTimeField(auto_now= True)

    USERNAME_FIELD = 'phone_number'
    REQUIRED_FIELDS = []

    objects = RegisterUserManager()

    def __str__(self):
        return self.phone_number

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

    def has_module_perms(self,perm,obj = None):
        return True

    @property
    def is_staff(self):
        return self.is_admin

views.py

from django.shortcuts import render
from django.http import HttpResponse,JsonResponse   
from rest_framework.parsers import JSONParser
from restaccount.models import RegisterUser
# Login
from restaccount.serializers import RegisterSerializers,LoginSerializer
# LoginSerializers
from django.views.decorators.csrf import csrf_exempt
from rest_framework.generics import CreateAPIView

from rest_framework_simplejwt.views import TokenObtainPairView

from rest_framework.permissions import (AllowAny,IsAuthenticated)
# from rest_framework.generics import CreateAPIView

class RegisterView(CreateAPIView):
    permission_classes = (AllowAny,)
    serializer_class = RegisterSerializers
    queryset = RegisterUser.objects.all()

class LoginView(TokenObtainPairView):
    serializer_class = LoginSerializer

serializers.py

from rest_framework.serializers import (ModelSerializer,ValidationError)
from restaccount.models import RegisterUser
# Login

from rest_framework_simplejwt.serializers import TokenObtainPairSerializer

from rest_framework import serializers

class RegisterSerializers(ModelSerializer):
    class Meta:
        model = RegisterUser
        fields =['id',
                'first_name',
                'last_name',
                'email',
                'password',
                'phone_number',
                'nickname',
                'birthday',
                ]

    def create(self,validated_data):
        first_name = validated_data['first_name']
        last_name = validated_data['last_name']
        email = validated_data['email']
        password = validated_data['password']
        phone_number = validated_data['phone_number']
        nickname = validated_data['nickname']
        birthday = validated_data['birthday']
        user_obj = RegisterUser(
            first_name = first_name,
            last_name = last_name,
            email = email,
            password = password,
            phone_number = phone_number,
            nickname = nickname,
            birthday = birthday,
        )
        user_obj.save()
        return user_obj

    def update(self, instance,validated_data):
        instance.first_name = validated_data.get('first_name',instance.first_name)
        instance.last_name = validated_data.get('last_name', instance.last_name)
        instance.email = validated_data.get('email', instance.email)
        instance.password = validated_data.get('password', instance.password)
        instance.phone_number = validated_data.get('phone_number', instance.phone_number)
        instance.nickname = validated_data.get('nickname', instance.nicknames)
        instance.birthday = validated_data.get('birthday',instance.birthday)
        instance.save()
        return instance

    def validate(self,data):
        return data
    
    def validate_phone_number(self,value):
        phone_number = value
        user_qs = RegisterUser.objects.filter(phone_number = phone_number)
        if user_qs.exists():
            raise ValidationError("This phone number is registered")
        return value


class LoginSerializer(TokenObtainPairSerializer):

    @classmethod
    def get_token(cls,user):
        token = super().get_token(user)

        token['phone_number'] = user.phone_number
        token['password'] = user.password

        return token

    def validate(self,attrs):
        data = super().validate(attrs)

        refresh = self.get_token(self.user)
        data['refresh'] = str(refresh)
        data['access'] = str(refresh.access_token)

        data['phone_number'] = self.user.phone_number

        return data

1 个答案:

答案 0 :(得分:0)

证明必须对模型中的密码字段进行哈希处理,以便 user.set_password(密码)。如果要从API端点创建用户,也是如此。您必须将哈希密码存储在数据库中。

但是,我不知道为什么是这种行为。