一 . 认证组件
我们现在知道的认证机制有cookie, session,session比较安全,session的信息是存在服务器上的,如果用户量足够大的话,服务器的压力也就比较大,并且django的session存到了django_session表中,不是很好操作,现在生产中使用的一个叫做token机制的方式比较多.可以使用这个机制把token存到用户信息里,当用户登录成功的时候放里面,等他来的时候就要带着这个来,而且们每次来的时候都更新token,防止被拦截.
我们这里使用一下token,首先要建一个表,和user表一对一关系
models.py
class User(models.Model): username = models.CharField(max_length=16) password = models.CharField(max_length=16) types = ((1, ‘VIP‘), (2, ‘SVIP‘), (3, ‘SSVIP‘)) usertype = models.IntegerField(choices=types, default=1) class UserToken(models.Model): user = models.OneToOneField(‘User‘) token = models.CharField(max_length=64)
URL
url(r‘^login/$‘, views.LoginView.as_view()), # 别忘了$符号结尾
视图函数,每次登录后自动刷新token
import uuid # 用户登录认证 class UserAuth(APIView): RET = { ‘code‘: None, ‘userinfo‘: None, ‘msg‘: None, ‘token‘: None } def post(self, request): username = request.data.get(‘username‘) password = request.data.get(‘password‘) user_obj = models.User.objects.filter(username=username, password=password).first() if user_obj: random_str = uuid.uuid4() models.UserToken.objects.update_or_create( # 有就更新,没有就创建 user=user_obj, defaults={ ‘token‘: random_str, } ) self.RET[‘code‘] = 0 # 跟前端约定好,0表示成功 self.RET[‘userinfo‘] = username self.RET[‘msg‘] = ‘success‘ self.RET[‘token‘] = random_str else: self.RET[‘code‘] = -1 self.RET[‘userinfo‘] = username self.RET[‘msg‘] = ‘failure‘ return Response(self.RET)
我们这里写一下DRF的认证组件
from rest_framework.exceptions import AuthenticationFailed from rest_framework.authentication import BaseAuthentication from app01 import models # drf提供认证失败的异常 class UserAuthToken(BaseAuthentication): # authenticate方法是固定的,并且必须写这个名字,是request新对象 def authenticate(self, request): token = request.query_params.get(‘token‘) # 类似于GET.get(‘token‘) token_obj = models.UserToken.objects.filter(token=token).first() if token_obj: return token_obj.user, token # 要么就返回两个值,要么就不返回 else: return AuthenticationFailed(‘认证失败‘)
我们需要把这个认证组件 写到每一个url对应的视图函数中,加上认证,有token就可以访问,没有就拒绝
class BookHandle(APIView): authentication_classes = [UserAuthToken, ] #一进到这个函数就进行验证,变量名必须是这个,认证组件需要从所在文件中导入 # 获取所有数据 def get(self, request): book_obj_list = models.Book.objects.all() book_res = BookSerializer(book_obj_list, many=True) return Response(book_res.data)
需要补两张成功与失败的对比图!!!
全局视图组件(写在settings.py中)
二 . 权限组件
权限组件
from rest_framework.permissions import BasePermission class UserPermission(BasePermission): message = "SVIP才能访问!" # 变量只能叫做message,权限不够的话返回message里面的数据 def has_permission(self, request, view): # view是用权限的视图函数 if request.user.usertype == 3: # user表中usertype的字段表示权限级别 return True # 通过权限,只能写True或False return False # 没有通过
视图函数
class BookHandle(APIView): permission_classes = [UserPer, ] # 一进函数就验证,只有有权限的才能访问下面的数据 # 获取所有数据 def get(self, request): book_obj_list = models.Book.objects.all() book_res = BookSerializer(book_obj_list, many=True) return Response(book_res.data)
全局视图权限(写在settings.py文件)
三 . 频率组件
内置的throttles类
from rest_framework.throttling import SimpleRateThrottle class VisitThrottle(SimpleRateThrottle): scope="visit_rate" # 限制访问次数用的 def get_cache_key(self, request, view): # 这个方法是固定的 return self.get_ident(request)
视图函数
class BookHandle(APIView): throttle_classes = [VisitThrottle, ] # 添加访问频率,需要从该类所在位置引入 # 获取所有数据 def get(self, request): book_obj_list = models.Book.objects.all() book_res = BookSerializer(book_obj_list, many=True) return Response(book_res.data)
原文地址:https://www.cnblogs.com/attila/p/10805858.html
时间: 2024-10-10 13:46:22