做一个Django项目(1.7、使用JWT完成认证并实现登陆)

  1. 导入模块
    pip install djangorestframework-jwt

     

  2. 添加配置
    REST_FRAMEWORK = {
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
            'rest_framework.authentication.SessionAuthentication',
            'rest_framework.authentication.BasicAuthentication',
        ),
    }
    
    JWT_AUTH = {
        'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
    }

     

  3. 注册完成后返回token
    from rest_framework_jwt.settings import api_settings
    
    class CreateUserSerializer(serializers.ModelSerializer):
        """
        创建用户序列化器
        """
        ...
        token = serializers.CharField(label='登录状态token', read_only=True)  # 增加token字段
    
        class Meta:
            ...
            fields = ('id', 'username', 'password', 'password2', 'sms_code', 'mobile', 'allow', 'token')  # 增加token
            ...
    
        def create(self, validated_data):
            """
            创建用户
            """
            # 移除数据库模型类中不存在的属性
            del validated_data['password2']
            del validated_data['sms_code']
            del validated_data['allow']
            user = super().create(validated_data)
    
            # 调用django的认证系统加密密码
            user.set_password(validated_data['password'])
            user.save()
    
            # 补充生成记录登录状态的token
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)
            user.token = token
    
            return user
  4. Django REST framework JWT提供了登录签发JWT的视图,可以直接使用
    from rest_framework_jwt.views import obtain_jwt_token
    
    urlpatterns = [
        url(r'^authorizations/$', obtain_jwt_token),
    ]
  5. 向登陆返回字段中添加额外的字段(在users模块下添加新建utils.py)
    def jwt_response_payload_handler(token, user=None, request=None):
        """
        自定义jwt认证成功返回数据
        """
        return {
            'token': token,
            'user_id': user.id,
            'username': user.username
        }
  6. 添加配置文件使其调用自定义的返回字段
    # JWT
    JWT_AUTH = {
        'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
        'JWT_RESPONSE_PAYLOAD_HANDLER': 'users.utils.jwt_response_payload_handler',
    }
  7. 重写登陆验证方法实现多账号登陆(修改Django认证系统的认证后端需要继承django.contrib.auth.backends.ModelBackend,并重写authenticate方法。
    1. 自定义登陆后端
      def get_user_by_account(account):
          """
          根据帐号获取user对象
          :param account: 账号,可以是用户名,也可以是手机号
          :return: User对象 或者 None
          """
          try:
              if re.match('^1[3-9]\d{9}$', account):
                  # 帐号为手机号
                  user = User.objects.get(mobile=account)
              else:
                  # 帐号为用户名
                  user = User.objects.get(username=account)
          except User.DoesNotExist:
              user = None
          finally:
              return user
      
      
      class UsernameMobileAuthBackend(ModelBackend):
          """
          自定义用户名或手机号认证
          """
      
          def authenticate(self, request, username=None, password=None, **kwargs):
              user = get_user_by_account(username)
              if user is not None and user.check_password(password):
                  return user
    2. 在配置文件中使用自定义的登陆
      # 修改默认的认证后端
      AUTHENTICATION_BACKENDS = [
          'users.utils.UsernameMobileAuthBackend',
      ]

 

你可能感兴趣的:(Django)