下面是对单个的视图进行的设置的:
请求的时候用postman然后发送信息
我们下面所有的举例都是在用户对Comment这个表的操作
首先先生成一个类似于cookie的字符串 发送给前端浏览器 然后下次它再访问带着这个认证字符串
登陆视图
#登陆视图 class LoginView(APIView): def post(self,request): ret = {"status":0} print(request.data) username = request.data.get("username") password = request.data.get('password') user_obj = models.UserInfo.objects.filter(username = username,password = password).first() # 校验看传递进来的是否对的 print(11111) if user_obj: print(2222222) #校验成功 加密并且写入 Token中它的 token = get_token_code(username) models.Token.objects.update_or_create(defaults={'token':token},user = user_obj) # 有就更新 没有就创建 ret['token'] = token #加密的内容存起来 else: ret['status'] = 1 ret['error'] = "用户名或密码错误" return Response(ret)
生成请求的token字符串:
#生成Token函数 def get_token_code(username): ''' 根据用户名和时间戳生成用户登陆成功过的随机字符串 :param username: 字符串格式用户名 :return: 字符串格式Token ''' import time import hashlib timestamp = str(time.time()) m = hashlib.md5(bytes(username,encoding="utf8")) m.update(bytes(timestamp,encoding="utf8")) return m.hexdigest()
认证: BaseAuthentication
from rest_framework.authentication import BaseAuthentication # 认证模块
抛错模块:
from rest_framework.exceptions import AuthenticationFailed # 模块报错 返回信息
我们可以根据这个来设置 登陆人的信息 只有登陆成功后才能进行提交post之类的操作
这个时候就用到了我们的权限设置
我们写一个文件来存放登陆的信息设置:
from rest_framework.authentication import BaseAuthentication # 认证模块 from first import models from rest_framework.exceptions import AuthenticationFailed # 模块报错 返回信息 import logging logger = logging.getLogger(__name__) class MyAuth(BaseAuthentication): def authenticate(self, request): print(request.method) if request.method in ["POST","PUT","DELETE"]: token = request.data.get("token") #获取你登陆的信息 token_obj = models.Token.objects.filter(token = token).first() #去数据库中阿奎那有没有这个数据 if token_obj: return token_obj.user,token else: raise AuthenticationFailed('无效的token') else: return None,None
views:
就是把你的认证设置导入进来 然后再用到post get操作的总操作的集合模块对操作设置
from first.utils.auth import MyAuth #导入你的 认证信息设置 class CommentViewSet(ModelViewSet): queryset = models.Comment.objects.all() serializer_class = first_serializers.Commentserializer #这个是你的对Comment的定义设置的 authentication_classes = [MyAuth] # 让你设置的认证生效
视图级别认证
class CommentViewSet(ModelViewSet): queryset = models.Comment.objects.all() serializer_class = app01_serializers.CommentSerializer authentication_classes = [MyAuth, ]
全局级别认证
# 在settings.py中配置 REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ] }
权限管理:BasePermission
from rest_framework.permissions import BasePermission #导入权限设置的模块
也是设置一个权限管理的模块:
from rest_framework.permissions import BasePermission #导入权限设置的模块 class MyPermission(BaseException): message = '快滚,没有权限!' def has_permission(self,request,view): ''' 判断该用户有没有权限 如果有就返回True 如果没有就返回False ''' print('我要进行自定义设置了') return True def has_object_permission(self,request,view,obj): # 重写父类的方法 名字必须这样 ''' obj是你的当前文章的作者对象 判断当前的评论用户作者是不是你当前的用户 只有评论的作者才能删除自己的评论 ''' if request.method in ['PUT',"DELETE"]: if obj.user == request.user: # 当前要删除的评论的作者就是当前登陆的用户 return True else: return False else: return True
views:
from first.utils.auth import MyAuth #导入你的 认证信息设置 from first.utils.permission import MyPermission #导入权限管理的模块 class CommentViewSet(ModelViewSet): queryset = models.Comment.objects.all() serializer_class = first_serializers.Commentserializer #这个是你的对Comment的定义设置的 authentication_classes = [MyAuth,] permission_classes = [MyPermission,] # 把你权限管理的设置导入进来
这个时候你就要给你的url设置了 就像之前解除的 继承全局的然后并不需要设置很多url 设置一个就可以
ursl:
from rest_framework.routers import DefaultRouter router = DefaultRouter() router.register(r'comment', views.CommentViewSet) #这个就是设置你的输入并且查找的视图 urlpatterns += router.urls
限制:
from rest_framework.throttling import SimpleRateThrottle
定义一个访问次数限制:
自定以的限制:
class VisitThorttle(SimpleRateThrottle): scope = "ooo" #这个名字随便起 是你设置全局的时候的给对应的 def get_cache_key(self, request, view): return self.get_ident(request) # 求当前访问的IP
其实上面是执行了这个流程:
''' 自定义访问限制类 ''' from rest_framework.throttling import BaseThrottle,SimpleRateThrottle from rest_framework.throttling import SimpleRateThrottle import time D = {} class MyThorttle(BaseThrottle): def allow_request(self, request, view): ''' 返回True就放行 返回False 表示被限制了 ''' # 获取当前的ip ip = request.META.get("REMOTE_ADDR") # 获取请求的IP print('这是自定义希纳是类的allow_request') print(ip) #获取当前时间 now = time.time() #判断当前ip是否有访问记录 if ip in D: D[ip] = [] #初始化一个空的访问历史列表 #高端 history = D[ip] while history and now -history[-1] > 30: #有ip并且当前时间减去储存的最后一个时间 history.pop() if len(history) >= 3: return False else: # 把这一次的访问时间加到访问历史列表的第一位 D[ip].insert(0,now) return True class VisitThorttle(SimpleRateThrottle): scope = "ooo" #这个名字随便起 def get_cache_key(self, request, view): return self.get_ident(request) # 求当前访问的IP
views:
from first.utils.throttle import VisitThorttle # 导入自定义访问限制 class CommentViewSet(ModelViewSet): queryset = models.Comment.objects.all() serializer_class = first_serializers.Commentserializer #这个是你的对Comment的定义设置的 throttle_classes = [VisitThorttle,] #把自定义的访问限制类
全局设置 全局的请求设置是你只要进去就会触发 而我们在views中的设置 只是有针对的对一些视图进行设置
全局设置:
在settings设置;
# rest framework相关的配置项 REST_FRAMEWORK = { 关于认证的全局配置 'DEFAULT_AUTHENTICATION_CLASSES': ['app01.utils.auth.MyAuth', ], 'DEFAULT_PERMISSION_CLASSES': ['app01.utils.permission.MyPermission'], #"DEFAULT_THROTTLE_CLASSES": ["app01.utils.throttle.MyThrottle", ], "DEFAULT_THROTTLE_RATES": { # 这个和上面的都可以设置 "ooo": "5/m", # ooo对应你后自定以的设置的scope "xxx": '10/m' } }