根据ip进行频率限制
写一个类,继承SimpleRateThrottle,只需要重写get_cache_key
from rest_framework.throttling import SimpleRateThrottle class MyThrottle(SimpleRateThrottle): scope = 'luffy' def get_cache_key(self, request, view): print('REMOTE_ADDR:',request.META.get('REMOTE_ADDR')) # print(request.META) return request.META.get('REMOTE_ADDR')
局部使用,全局使用
python manage.py runserver 0.0.0.0:8000
jwt
1 控制用户登录后才能访问,和不登录就能访问
from rest_framework_jwt.authentication import JSONWebTokenAuthentication # 内置权限类 # 可以通过认证类:JSONWebTokenAuthentication 和权限类IsAuthenticated, 来控制用户登录以后才能访问某些接口 # 如果用户不登录就可以访问,只需要把权限类IsAuthenticated去掉就可以了 from rest_framework.permissions import IsAuthenticated class OrderAPIView(APIView): # 登录才能访问 authentication_classes = [JSONWebTokenAuthentication,] # 权限控制 permission_classes = [IsAuthenticated,] def get(self,request,*args,**kwargs): return Response('这是订单信息') class UserInfoAPIView(APIView): # 不登录就可以访问 authentication_classes = [JSONWebTokenAuthentication,] def get(self,request,*args,**kwargs): return Response('UserInfoAPIView')
2 控制登录接口返回的数据格式
- 第一种方案,自己写登录接口
- 第二种方案,用内置,控制登录接口返回的数据格式
jwt的配置信息中有这个属性:
'JWT_RESPONSE_PAYLOAD_HANDLER': 'rest_framework_jwt.utils.jwt_response_payload_handler',
重写jwt_response_payload_handler,配置成咱自己的,settings.py
JWT_AUTH = { 'JWT_RESPONSE_PAYLOAD_HANDLER': 'app02.utils.my_jwt_response_payload_handler', }
utils.py
def my_jwt_response_payload_handler(token, user=None, request=None): # 返回什么,前端就能看到什么样子 """ Returns the response data for both the login and refresh views. Override to return a custom response such as including the serialized representation of the User. Example: def jwt_response_payload_handler(token, user=None, request=None): return { 'token': token, 'user': UserSerializer(user, context={'request': request}).data } """ return { 'token': token, 'msg':'登录成功', 'status':100, 'username':user.username, # 'password':user.password }
手动签发token(多方式登录)
使用用户名,手机号,邮箱,都可以登录
前端需要传的数据格式
{ "username":"jeffrey/18605811419/arbitter@163.com", "password":"12345", }
ser.py
from rest_framework import serializers from api import models import re from rest_framework.exceptions import ValidationError from rest_framework_jwt.utils import jwt_encode_handler,jwt_payload_handler class LoginModelSerializer(serializers.ModelSerializer): username = serializers.CharField() # 重新覆盖username字段,数据中它是unique,认为你保存数据,自己有校验 class Meta: model = models.User fields = ['username','password'] def validate(self, attrs): print(self.context) # 在这写逻辑 username = attrs.get('username') password = attrs.get('password') # 通过判断,username数据不同,查询字段不一样 # 正则匹配,如果是手机号 if re.match('^1[3-9][0-9]{9}$',username): user = models.User.objects.filter(mobile=username).first() elif re.match('^.+@.+$',username): #邮箱 user = models.User.objects.filter(email=username).first() else: user = models.User.objects.filter(username=username).first() if user: #存在用户 # 校验密码,因为是密文,所以要用check_password() if user.check_password(password): # 签发token payload = jwt_payload_handler(user) token = jwt_encode_handler(payload) self.context['token'] = token self.context['username'] =user.username return attrs else: raise ValidationError('密码错误') else: raise ValidationError('用户名不存在')
views.py
class Login2View(ViewSet): # 跟上面完全一样 # 这是登录接口 # def post(self,request): # 不写post,直接写login? # pass def login(self, request, *args, **kwargs): # 1. 需要 有个序列化的类 login_ser = ser.LoginModelSerializer(data=request.data, context={'request': request}) # 2. 生成序列化类对象 # 3. 调用序列化对象的is_valid login_ser.is_valid(raise_exception=True) token = login_ser.context.get('token') username = login_ser.context.get('username') # return return Response({'status': 100, 'msg': '登录成功', 'token': token, 'username': username})
基于角色的权限控制(django内置auth体系)
RBAC: 就是基于角色的访问控制(Role-based Access Control),公司内部系统
django的auth就是内置了一条基于RBAC的权限系统
django中
后台的权限控制(公司内部系统 crm,erp,系统平台)
user表
permission表
group表
user_groups表是 user和group的中间表
group_permissions表是group和permission的中间表
user_permissions 是user和permission的中间表
前台(主站),需要用三大认证(认证,权限和频率)
django缓存
前端混合开发缓存的使用
缓存的位置,通过配置文件来操作(以文件为例)
缓存的粒度:
全站缓存
中间件
MIDDLEWARE = [ 'django.middleware.cache.UpdateCacheMiddleware', 'django.middleware.cache.FetchFromCacheMiddleware', ] CACHE_MIDDLEWARE_SECONDS = 10 # 全站缓存10秒钟
单页面缓存
在视图函数上加装饰器
from django.views.decorators.cache import cache_page @cache_page(5) # 缓存5秒钟 def test_cache(request): ctime = time.time() return render(request,'index.html',locals())
页面局部缓存
{% load cache %} {% cache 5 'name' %} #5 表示5秒钟,name是唯一key值 {{ ctime }} {% endcache %}
前后端分离缓存的使用
如何使用
from django.core.cache import cache # @cache_page(5) # 缓存5秒钟 def test_cache(request): p = Person('jeffrey',20) cache.set('name', p) ctime = time.time() return render(request, 'index.html', locals()) def test_cache2(request): p = cache.get('name') print(type(p)) print(p) print(p.name) ctime = time.time() return render(request, 'index.html', locals
cache.set('key',value可以是任意数据类型)
cache.get('key')
应用场景:
第一次查询所有图书,通过多表联查序列化之后的数据,直接缓存起来
后续直接先去缓存查,如果有直接返回,没有,再去联表查询,返回之前再缓存