自定义JWT的签发

自定义user表签发token

使用自己的user表进行签发验证需要自己写 登录接口 和 认证类

1 路由

from rest_framework.routers import SimpleRouter
from rest_framework_jwt.views import obtain_jwt_token

router = SimpleRouter()
router.register('book', views.BookView)
router.register('user', views.UserInfoView, basename='user')

urlpatterns = [
    path('', include(router.urls)),
]

2 视图类

from app01 import serializer, models, auth
from rest_framework.viewsets import ModelViewSet,ViewSet
from rest_framework.response import Response
from rest_framework.decorators import action

# Book接口
class BookView(ModelViewSet):
    queryset = models.Books.objects.all()
    serializer_class = serializer.BookSerializer

    authentication_classes = [auth.JWTAuthentication2, ]


# 登录接口
from rest_framework_jwt.settings import api_settings
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
class UserInfoView(ViewSet):
    @action(methods=['POST'], detail=False)
    def login(self, request):
        # 获取用户名和密码,去数据库中校验
        username = request.data.get('username')
        password = request.data.get('password')
        res = {'code': 100, 'msg': ''}
        user = models.User.objects.filter(username=username, password=password).first()
        if user:
            # 校验成功后生成token(生成token的函数模块提供了,导入就行)
            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)
            res['token'] = token
            res['msg'] = '登录成功!'
        else:
            res['code'] = 101
            res['msg'] = '用户名或密码错误!'
        return Response(res)

3 认证类

from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication
from rest_framework_jwt.utils import jwt_decode_handler
import jwt
from rest_framework.exceptions import AuthenticationFailed
from app01.models import User
class JWTAuthentication2(BaseJSONWebTokenAuthentication):
    def authenticate(self, request):
        token = request.META.get('HTTP_AUTHORIZATION', None)
        if token:
            try:
                payload = jwt_decode_handler(token)
            except jwt.ExpiredSignature:
                raise AuthenticationFailed('签名已过期。')
            except jwt.DecodeError:
                raise AuthenticationFailed('签名认证失败。')
            except jwt.InvalidTokenError:
                raise AuthenticationFailed('签名已失效。')

        else:
            raise AuthenticationFailed('认证失败。')

        user = User.objects.filter(pk=payload.get('user_id'))
        # 优化,减少数据库压力
        # user=User(id=payload.get('user_id'),username=payload.get('username'))
        # user={'id':payload.get('user_id'),'username':payload.get('username')}
        return (user, token)

posted @ 2021-07-23 21:30  zheng-sn  阅读(152)  评论(0)    收藏  举报