1. 安装simplejwt库并修改settings.py

  1. 安装simplejwt

    pip install djangorestframework
    pip install djangorestframework-simplejwt
    
  2. 修改settings.py

    • 注册应用

      INSTALLED_APPS = [
          ...
          'rest_framework',
          'rest_framework_simplejwt',
      ]
      
    • 设置jwt鉴权

      REST_FRAMEWORK = {
          'DEFAULT_AUTHENTICATION_CLASSES': [
              'rest_framework_simplejwt.authentication.JWTAuthentication',  # 使用rest_framework_simplejwt(token)验证身份
          ],
          'DEFAULT_PERMISSION_CLASSES': [
              'rest_framework.permissions.IsAuthenticated'  # 设置全局所有视图需要jwt鉴权
          ],
      }
      
    • 配置token相关参数(非必须,按需配置)

      SIMPLE_JWT = {
          'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),  # 可以修改这个值来改变token的过期时间
          'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
          'ROTATE_REFRESH_TOKENS': True,
          'BLACKLIST_AFTER_ROTATION': True,
      
          'ALGORITHM': 'HS256',  # 对称算法:HS256 HS384 HS512  非对称算法:RSA
          'SIGNING_KEY': SECRET_KEY,
          'VERIFYING_KEY': None,  # if signing_key, verifying_key will be ignore.
          'AUDIENCE': None,
          'ISSUER': None,
      
          'AUTH_HEADER_TYPES': ('Bearer',),  # Authorization: Bearer <token>
          'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',  # if HTTP_X_ACCESS_TOKEN, X_ACCESS_TOKEN: Bearer <token>
          'USER_ID_FIELD': 'id',  # 使用唯一不变的数据库字段,将包含在生成的令牌中以标识用户
          'USER_ID_CLAIM': 'user_id',
      }
      
    • 连接数据库

      DATABASES = {
          'default': {
              'ENGINE': 'django.db.backends.mysql',
              'NAME': 'testdb',
              'USER': 'root',
              'PASSWORD': 'xxxxxx',
              'HOST': '127.0.0.1',
              'PORT': '3306',
          }
      }
      
    • MIDDLEWARE删除’django.middleware.csrf.CsrfViewMiddleware’

      前后端分离的项目,引入了jwt,需要将csrf去掉,否则接口都报错403

2. 生成token

  1. 我的接口定义在user子模块,所以,需要先创建user子模块

    在PyCharm -> Tools -> Run manage.py Task 中执行命令

    # 创建user子模块
    startapp user
    
    # 迁移数据表
    makemigrations
    migrate
    
  2. 在user子模块中创建urls.py文件

    from django.urls import path
    from rest_framework_simplejwt.views import (
        TokenObtainPairView,
        TokenRefreshView,
        TokenVerifyView,
    )
    
    # rest_framework_simplejwt自带三个视图TokenObtainPairView、TokenVerifyView、TokenRefreshView,用于生成token、验证token、刷新token
    urlpatterns = [
        path('login', TokenObtainPairView.as_view(), name='token_obtain_pair'),
        path('verify', TokenVerifyView.as_view(), name='token_verify'),
        path('refresh', TokenRefreshView.as_view(), name='token_refresh'),
    ]
    
  3. 在主模块的urls.py文件中引入user子模块

    from django.urls import path, include
    
    urlpatterns = [
        path('user/',include('user.urls')),
    ]
    
  4. 调用接口验证,发现并不能生成token

    在这里插入图片描述

    在这里插入图片描述

    原因:框架使用的是auth_user数据表的用户,对于不存在于auth_user数据表的用户名和密码,调用接口会报上面的错误。

    解决方案:在PyCharm -> Tools -> Run manage.py Task 中执行命令,创建用户

    createsuperuser
    

    在这里插入图片描述

此时在auth_user表中会新增一行用户名为admin的数据,再次调用接口,执行成功。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3. 使用自定义用户模型

如果不想使用auth_user表,想要自定义用户表,则自定义的用户模型需要继承AbstractUser

  1. 在user/model.py中新增模型,只需添加自定义的字段,username、password、email等字段在AbstractUser中包含。

    class SysUser(AbstractUser):
        avatar = models.CharField(max_length=255, null=True, verbose_name="头像")
        phone_number = models.CharField(max_length=11, null=True, verbose_name="手机号")
        status = models.IntegerField(null=True, default=0, verbose_name="帐号状态(0正常,1停用)")
        remark = models.CharField(max_length=1024, null=True, verbose_name="备注")
    
        class Meta:
            db_table = 'sys_user'
    
  2. 模型序列化

    在user/model.py中新增

    from rest_framework import serializers
    
    class SysUserSerializer(serializers.ModelSerializer):
        class Meta:
            model = SysUser
            fields = '__all__'
    
  3. 在settings.py中设置使用自定义用户类进行JWT鉴权 (配置为:app真实名称.自定义模型类名)

    AUTH_USER_MODEL = 'user.SysUser'
    
  4. 执行数据迁移

    makemigrations
    migrate
    

    此时数据库中会新建数据表sys_user。

  5. 自定义注册视图,用于注册用户

    在user/views.py中新增RegisterView

    @authentication_classes([])
    @permission_classes([])
    class RegisterView(APIView):
        def post(self, request):
            serializer = SysUserSerializer(data=request.data)
            if serializer.is_valid():
                user = SysUser(**serializer.validated_data)
                # 对密码加密
                user.set_password(serializer.validated_data['password'])
                user.save()
                return Response(serializer.data, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    

    在user/urls.py新增path

    path('register', RegisterView.as_view(), name='register'),
    

    注意:

    • @authentication_classes([]) 和 @permission_classes([]) 这两个装饰器用于对某个视图去除jwt鉴权
    • 密码一定要加密,否则会鉴权失败

    调用接口测试:

    在这里插入图片描述

  6. 自定义登录视图,继承TokenObtainPairView

    在user/views.py中新增LoginView

    class LoginView(TokenObtainPairView):
        def post(self, request, *args, **kwargs):
            serializer = self.get_serializer(data=request.data)
            try:
                serializer.is_valid(raise_exception=True)
            except TokenError as e:
                raise InvalidToken(e.args[0])
    
            return Response(serializer.validated_data, status=status.HTTP_200_OK)
    

    再次调用login接口,生成token成功。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐