JWT的综合使用

JWT的综合使用

自己写的认证类,使用自己的user表签发token,有多种登录方式,

urls.py

from django.contrib import admin
from django.urls import path,include
from app01 import views
from rest_framework.routers import SimpleRouter
routers = SimpleRouter()
routers.register('user',views.UserInfoView,basename='user')
routers.register('book',views.BookView)

urlpatterns = [
    path('',include(routers.urls)),
    path('admin/', admin.site.urls),
]

models.py

from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.


class User(AbstractUser):
    phone=models.CharField(max_length=32)


class Books(models.Model):
    name = models.CharField(max_length=32)
    price = models.IntegerField()

views.py

from django.shortcuts import render
# Create your views here.
from rest_framework.viewsets import ViewSet,ModelViewSet
from rest_framework.decorators import action
from app01 import serializers,models,auth
from rest_framework.response import Response


class UserInfoView(ViewSet):
    @action(methods=['POST'],detail=False)
    def login(self, request):
        res = {'code': 100, 'msg': ''}
        user_ser = serializers.UserSerializer(data=request.data)
        if user_ser.is_valid():
            res['msg'] = '登录成功'
            res['tokne'] = user_ser.context['token']
        else:
            res['msg'] = '登录失败'
            res['code'] = 101

        return Response(res)


class BookView(ModelViewSet):
    queryset = models.Books.objects.all()
    serializer_class = serializers.BookSerializer
    authentication_classes = [auth.LoginAuth,]

serializers.py

from rest_framework import serializers
from app01 import models
import re
from rest_framework.exceptions import ValidationError
from rest_framework_jwt.utils import jwt_payload_handler,jwt_encode_handler


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model=models.User
        fields=['username','password']

    username=serializers.CharField()

    def validate(self, attrs):
        username = attrs.get('username')
        password = attrs.get('password')
        if re.match(r'^1[3-9][0-9]{9}$', username):
            user = models.User.objects.filter(phone=username).first()
        elif re.match(r'^.+@.+$', username):
            user = models.User.objects.filter(email=username).first()
        else:
            user =models.User.objects.filter(username=username).first()

        if user:
            if user.check_password(password):
                payload = jwt_payload_handler(user)
                token = jwt_encode_handler(payload)
                self.context['token'] = token
                return attrs
            else:
                raise ValidationError('用户名或密码错误!')
        else:
            raise ValidationError('用户名或密码错误!')


class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model=models.Books
        fields='__all__'

auth.py

from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication
from rest_framework_jwt.utils import jwt_decode_handler
from rest_framework.exceptions import AuthenticationFailed
import jwt
from app01 import models


class LoginAuth(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 = models.User.objects.filter(pk=payload['user_id'])

        return (user,token)
posted @ 2021-07-23 21:31  zheng-sn  阅读(50)  评论(0)    收藏  举报