基于自定义表签发token
1 快速签发和认证
2 定制返回格式和认证
3 自定义登录和认证
4 自定义登录,自定义表
5 自定义认证类
url.py
from django.contrib import admin
from django.urls import path
from rest_framework.routers import SimpleRouter
from .views import UserView
router = SimpleRouter()
router.register('user', UserView, 'user')
urlpatterns = [
]
urlpatterns += router.urls
view.py
from rest_framework.decorators import action
from rest_framework.viewsets import GenericViewSet
from rest_framework.response import Response
from .serializer import LoginSerializer
class UserView(GenericViewSet):
serializer_class = LoginSerializer
# 127.0.0.1:8000/api/v1/user/login/
@action(methods=['POST'], detail=False)
def login(self, request):
ser = self.get_serializer(data=request.data)
ser.is_valid(raise_exception=True)
return Response(ser.validated_data)
序列化类
from rest_framework import serializers
from .models import UserInfo
from rest_framework.exceptions import APIException
from rest_framework_simplejwt.tokens import RefreshToken
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer, TokenObtainSerializer
# 只做校验
class LoginSerializer(serializers.Serializer):
username = serializers.CharField()
password = serializers.CharField()
def validate(self, attrs):
username = attrs.get('username')
password = attrs.get('password')
user = UserInfo.objects.filter(username=username, password=password).first()
if user:
# 签发token,使用RefreshToken直接签发
refresh = RefreshToken.for_user(user)
return {
'code': 100,
'msg': '登录成功',
'username': username,
# 'icon':user.icon,
'access': str(refresh.access_token),
'refresh': str(refresh)
}
else:
raise APIException({'code': 999, 'msg': '用户名或密码错误11'})
表模型
class UserInfo(models.Model):
username = models.CharField(max_length=32)
password = models.CharField(max_length=32)
age = models.IntegerField()
gender = models.IntegerField(choices=((1, '男'), (2, '女'), (0, '未知')))
基于自定义表编写认证类
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import APIException
from rest_framework_simplejwt.tokens import AccessToken
from rest_framework_simplejwt.authentication import JWTAuthentication
# JWTAuthentication 有authenticate 里面完成对token的认证
from .models import UserInfo
class LoginAuthentication(BaseAuthentication):
def authenticate(self, request):
# 1 取出前端传入的token:它放哪了?后端定的:定死key值叫token:value值直接不带任何前缀
token = request.META.get('HTTP_TOKEN')
if token:
# validated_token = self.get_validated_token(token)---》返回了AccessToken(token)传入的对象
# 2 拿到token,验证token是否合法,是否过期,是否被篡改,伪造,如果都通过,根据payload中得userid取出当前用户
try:
validated_token = AccessToken(token) # 源码中拿出来的
except Exception as e:
raise APIException({'code': 888, 'msg': str(e)})
# 3 取出用户id,根据用户id,查出用户,返回
# validated_token.payload['user_id']
# validated_token['user_id']
user = UserInfo.objects.filter(pk=validated_token['user_id']).first()
return user, token
else:
raise APIException({'code': 101, 'msg': 'token必须携带'})