django_rest_frameworker jwt 是基于django自带的认证系统(库中的auth.user表)来实现的,
也就是说我们的用户表(user)需要直接继承django自带的AbstractUser表,在此基础上添加字段。
网上大部分的文章也是默认这么做的。
由于事先已经自定义的user表,而且没有继承 AbstractUser,所以需要重写一些方法来使用我们自建的user表数据。
from rest_framework_jwt.utils import jwt_decode_handler import jwt from rest_framework.exceptions import AuthenticationFailed from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication from account.models import User class JwtAuthentication(BaseJSONWebTokenAuthentication): """ 当User表为自定义的表,而且没有继承自django自带的auth.User表时,需要重写验证方法:authenticate """ def authenticate(self, request): token = request.META.get('HTTP_Authorization'.upper()) print(token) try: payload = jwt_decode_handler(token) except jwt.ExpiredSignature: raise AuthenticationFailed('亲,token放太久了,都过期了,快去重新获取吧!') except jwt.DecodeError: raise AuthenticationFailed('token为空或者解码错误') except jwt.InvalidTokenError: raise AuthenticationFailed('不合法的token') # 得到的user对象,应该是自己user表的user对象 # print(payload) # payload内容:{'user_id': 1, 'username': '66559575', 'exp': 1620538525, 'email': '66559575@cho.cn'} user = User.objects.get(id=payload['user_id']) # user = payload return user, token
其中的关键就是获取user实例,user= User.objects.get(id=payload['user_id'])
在settings.py中仍然需要配置
REST_FRAMEWORK = { 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'], 'DATETIME_FORMAT': "%Y-%m-%d %H:%M:%S", # 自定义分页器类 'DEFAULT_PAGINATION_CLASS': 'common.DRF_Paginate.CustomPagination', 'PAGE_SIZE': 10, # 每页数目 'DEFAULT_AUTHENTICATION_CLASSES': [ # 使用JWT Token认证 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', # Basic类型的认证(账号和密码) 'rest_framework.authentication.SessionAuthentication', # Session会话认证 'rest_framework.authentication.BasicAuthentication', ], } JWT_AUTH = { # 设置token过期时间 'JWT_EXPIRATION_DELTA': datetime.timedelta(hours=1), # seconds=300 5分钟 # token前缀 # 'JWT_AUTH_HEADER_PREFIX': 'JWT', }
在视图类中添加 authentication_classes = [JwtAuthentication],指定上面自定义的认证类
class ListSubSys(generics.ListAPIView): """ 获取子系统列表 """ queryset = SubSys.objects.all() serializer_class = SubSysSerializers # 使用自定义分页 pagination_class = CustomPagination # 模糊匹配查询 filterset_class = sub_sys_filter.SubSysFilter # JWT认证,使用自定义的JwtAuthentication,继承自JSONWebTokenAuthentication authentication_classes = [JwtAuthentication] # permission_classes = [IsAuthenticated]
认证功能局部使用和全局使用
# 1 全局使用(所有接口,都需要登录才能访问) -在配置文件中 REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ["app01.myauthen.LoginAuth", ] } #2 局部使用 -在想局部使用的视图类上写上下面这条 authentication_classes = [myauthen.LoginAuth,] #3 局部禁用 -在想禁用的视图类上 authentication_classes = []