在阐述什么是装饰器前,我们先来说一下什么是闭包
def outer( ):
a=100
def inner( ):
b=a+100
print(b)
return inner
outer( )( )
以@开头,装饰器是在函数调用之上的修饰器,在不改变项目原有代码的基础上,增加一些额外的功能
装饰器使用场景
授权:装饰器能有助于检查某个人是否被授权去使用一个web应用的端点(endpoint)。它们被大量使用于Flask和Django web框架中
日志:在记录日志的地方添加装饰器
缓存:通过装饰器获取缓存中的值
一个装饰器:
def outer(func):
def inner(a,b) / def inner( *args,**kwargs):
print("特殊效验功能的执行")
func(a,b) / func( *args,**kwargs)
print("停止执行")
return inner
@outer
def f(a,b):
print("a+b=",(a+b))
f(10,20)
# 输出结果:
特殊效验功能的执行
30
停止执行
多个装饰器:
开始: 自上而下
结束: 自下而上
def outer1(func):
def inner(a,b) / def inner( *args,**kwargs):
print("特殊效验功能 1 的执行")
print("111111111111")
func(a,b) / func( *args,**kwargs)
print("1 停止执行")
print("111111111111")
return inner
def outer2(func):
def inner(a,b) / def inner( *args,**kwargs):
print("特殊效验功能 2 的执行")
print("222222222222")
func(a,b) / func( *args,**kwargs)
print("2 停止执行")
print("222222222222")
return inner
@outer1
@outer2
def f(a,b):
print("a+b=",(a+b))
f(10,20)
#输出结果: 特殊功能效验 1 的执行
111111111111
特殊功能效验 2 的执行
222222222222
30
2 停止执行
222222222222
1 停止执行
111111111111
这里的代码,展示的是 jwt 和 类装饰的结合使用
目的: 防止用户 使用他人敏感信息 进行篡改
import jwt
#装饰器
def my_decorator(func):
def wrapper(request,*args,**kwargs):
print('这个装饰器被调用了')
print('请求接口地址是%s' % request.path)
#判断jwt逻辑
uid = request.GET.get("uid")
clinet_jwt = request.GET.get("jwt",None)
if clinet_jwt is None:
return HttpResponse('没有令牌')
decode_jwt = jwt.decode(clinet_jwt,'123',algorithms=['HS256'])
if decode_jwt['uid'] != str(uid):
return HttpResponse('你篡改了用户id')
return func(request,*args,**kwargs)
return wrapper
#类装饰器调用
from django.utils.decorators import method_decorator
在查询用户信息类时 调用
#用户信息
class UserInfo(APIView):
@method_decorator(my_decorator)
def get(self,request):
uid = request.GET.get('uid')
#查询数据
user = User.objects.get(id=int(uid))
#序列化对象
user_ser = UserSer(user)
return Response(user_ser.data)
在 用户登录接口 后端
#登录接口
class Login(APIView):
def get(self,request):
#接收参数
username = request.GET.get('username','没有接受到')
password = request.GET.get('password','没有接受到')
#查询数据
user = User.objects.filter(username=username,password=make_password(password)).first()
if user:
res = {
}
res['code'] = 200
res['message'] = '登录成功'
res['username'] = user.username
res['uid'] = user.id
#加入jwt 编码机制
#进行编码
encode_jwt = jwt.encode({
'uid':str(user.id)},'123',algorithm='HS256')
#解码操作
#强转
encode_str = encode_jwt.decode('utf-8')
res['jwt'] = encode_str
return Response(res)
else:
res = {
}
res['code'] = 405
res['message'] = '用户名或密码错误'
return Response(res)
在前端的登录 接口中 要将 jwt 存储到 localStorage 里面
localStorage.setItem('jwt',result.data.jwt)