自定义字段,不参与反/序列化:
反序列化之前拦截
Django基于角色的权限认证(6表)
Django基于角色的权限认证(6表多对多字段,正反查询)
admin设置显示中文
drf认证组件与权限组件
REST_FRAMEWORK = { 1.'DEFAULT_AUTHENTICATION_CLASSES': [ # 自定义认证类 - 重写authenticate - 通过(user和auth | None) 失败(raise) 'rest_framework.authentication.SessionAuthentication', # 前台sessionid与后台django_session完成认证,赋值给request.user 'rest_framework.authentication.BasicAuthentication', ], 2.'DEFAULT_PERMISSION_CLASSES': [ # 自定义权限类 (主要获取request.user)- has_permission - 通过(True) | 失败(False) 'rest_framework.permissions.AllowAny', 'rest_framework.permissions.IsAuthenticated', # 校验是否有request.user 'rest_framework.permissions.IsAuthenticatedOrReadOnly', # 查操作不校验request.user,增改删校验request.user 'rest_framework.permissions.IsAdminUser', # 是否是在职用户(request.user.is_staff) ], }
自定义权限组件
settings.py:
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication', ], 'DEFAULT_PERMISSION_CLASSES': [ # 'api.permissions.IsSuperUserPermission' # 自定义是否是超级管理员(request.user.is_superuser) ], }
自定义权限类:
视图是否使用权限组件:
admin密文操作密码
jwt:json web tokens(发展史)
jwt的tokens
组成:
头+体+签名
头:{公司基本信息,加密方式} => base64加密
体(载荷):{用户信息,过期时间} => base64加密
签名:{头,体,密钥} => hash256加密
签发token:
登陆的用户、过期时间、服务器密钥 + 基础信息们
校验token:
前台的头、前台的体、服务器密钥
安装:
pip3 install djangorestframework-jwt
自定义jwt登录实现签发token
from rest_framework.views import APIView from rest_framework_jwt.serializers import jwt_payload_handler from rest_framework_jwt.serializers import jwt_encode_handler from django.contrib import auth # 自定义jwt登陆 class LoginAPIView(APIView): def post(self, request, *args, **kwargs): username = request.data.get('username') password = request.data.get('password') if not (username and password): return Response({ 'error': 'username与password为必须字段' }) user_obj = auth.authenticate(username=username, is_active=True, password=password) if user_obj: # 签发token payload = jwt_payload_handler(user_obj) token = jwt_encode_handler(payload) return Response({ 'status': 0, 'msg': 'ok', 'token': token }) else: return Response({ 'status': 1, 'msg': 'username与password有误' })
自定义jwt实现验证token
自定义验证token类:
import jwt from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication from rest_framework_jwt.authentication import jwt_decode_handler from rest_framework import exceptions class JWTAuthentication(BaseJSONWebTokenAuthentication): def authenticate(self, request): jwt_value = request.META.get('HTTP_TOKEN') if jwt_value is None: return None try: payload = jwt_decode_handler(jwt_value) except jwt.ExpiredSignature: raise exceptions.AuthenticationFailed('token已过期') except jwt.InvalidTokenError: raise exceptions.AuthenticationFailed('token非法') user = self.authenticate_credentials(payload) return (user, jwt_value)
view视图:
from rest_framework.viewsets import ModelViewSet from . import models, serializers from rest_framework.response import Response from . import permissions from rest_framework.permissions import IsAuthenticated from rest_framework_jwt.authentication import JSONWebTokenAuthentication from api.authentications import JWTAuthentication class CarsModelViewSet(ModelViewSet): # 必须完成jwt校验才能得到登陆状态 # authentication_classes = [JSONWebTokenAuthentication] #系统验证token authentication_classes = [JWTAuthentication] #自定义验证token # 登陆后才能查看 permission_classes = [IsAuthenticated] queryset = models.Car.objects.filter(is_delete=False) serializer_class = serializers.CarsModelSerializer def destroy(self, request, *args, **kwargs): return Response('该功能暂无提供')
设置token过期时间
import datetime JWT_AUTH = { 'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=300), # 过期时间 }