10Django-自定义验证用户登录装饰器并将装饰器应用到用户更新操作的视图中
1基础知识:
方法装饰器:用在类的函数里
函数装饰器:直接用在函数上
把方法装饰器转换成函数装饰器的方法是使用@method_decorator()工具
2搭建方法装饰器的架子国定写法:
def logging_check(func): def wrap(request, *args, **kwargs): return func(request, *args, **kwargs) return wrap
3自定义校验用户token及用户名的方法装饰器
1)知识点
因为我们生成令牌用的是:jwt.encode(payload_data,key,algorithm='HS256')
所以我们解密令牌的方法就是:jwt.decode(token, key,algorithms='HS256')
2)程序逻辑:
首先我从浏览器请求头中拿到前端传过来的token,然后我用decode()方法对token进行解密,因为我们生成令牌的方法中包含username,所以此时的解密肯定是可以通过字典的形式拿到用户的,
然后我们在request中自定义一个用户,让这个用户等于获取到的用户,目的是为了方便视图时调用,减少视图的代码量,
3)具体代码如下:
#校验登录状态装饰器 from django.http import JsonResponse from django.conf import settings import jwt from user.models import UserProfile def logging_check(func): def wrap(request, *args, **kwargs): #取浏览器请求头Authorization的值(取token:request.META.get('HTTP_AUTHORIZATION')) token = request.META.get('HTTP_AUTHORIZATION') if not token: result = {'code':403,'error':'没有获取到令牌,登录状态失效,你是不是没登录呀?'} return JsonResponse(result) #校验token try: res = jwt.decode(token, settings.JWT_TOKEN_KEY,algorithms='HS256') except Exception as e: print('jwt decode error is %s'%(e)) result = {'code':403,'error':'令牌校验失败,非法入侵'} return JsonResponse(result) #获取登录用户 try: username = res['username'] user = UserProfile.objects.get(username=username) #在request里定义一个myuser,让我们自定义的这个用户等于获取到的用户,注意myuser的起码方式,一定要避免和系统保留字段重名 request.myuser = user except Exception as e: result = {'code':208,'error':'用户不存在'} return JsonResponse(result) return func(request, *args, **kwargs) return wrap
4)将校验用户登录状态的装饰器应用到视图当中:
import json from django.http import JsonResponse from django.shortcuts import render from django.utils.decorators import method_decorator from django.views import View from .models import UserProfile import hashlib from tools.logging_dec import logging_check # Create your views here. class UserViews(View): #获取个人信息 def get(self,request,username=None): if username: #/v1/users/zhangsan try: user = UserProfile.objects.get(username=username) except Exception as e: result = {'code':208, 'error':'用户名不存在'} return JsonResponse(result) result = {'code':200,'username':username, 'data':{'info':user.info,'sign':user.sign,'nickname':user.nickname,'avatar':str(user.avatar)}} return JsonResponse(result) #用户注册 def post(self,request): json_str = request.body #获取前端的json提交 json_obj = json.loads(json_str) #把json串转换成python的对象 username = json_obj.get('username') email = json_obj.get('email') password1 = json_obj.get('password1') password2 = json_obj.get('password2') phone = json_obj.get('phone') #参数的基本检查 if password1 != password2: result = {'code':206,'error':'两次提交密码不一致'} #把json对象转换成json串返给浏览器 return JsonResponse(result) #1检查用户名是否可用 queryset_users = UserProfile.objects.filter(username=username) if queryset_users: result = {'code':207,'error':'用户名已存在'} return JsonResponse(result) #手机号不能重复 queryset_phone = UserProfile.objects.filter(phone=phone) if queryset_phone: result = {'code':210,'error':'手机号已存在'} return JsonResponse(result) #给明文密码加密 hash_object = hashlib.md5() hash_object.update(password1.encode()) #md5要求字节串而password1是字符串,必须转换 pwd = hash_object.hexdigest() #已经设置默认值的字段,在创建订单时可以不写 UserProfile.objects.create(username=username,nickname=username,password=pwd,email=email,phone=phone) result = {'code':200,'username':username,'data':{}} return JsonResponse(result) #更新用户信息[昵称,签名,个人描述] @method_decorator(logging_check) def put(self,request,username=None): #获取所有数据 json_str = request.body #把json串转换成字典 json_obj = json.loads(json_str) # #取用户(一查) # try: # user = UserProfile.objects.get(username=username) # except Exception as e: # result = {'code':208,'error':'用户名不存在'} # return JsonResponse(result) user = request.myuser #修改数据(二改) user.sign = json_obj['sign'] user.info = json_obj['info'] user.nickname = json_obj['nickname'] #保存数据(三更新) user.save() return JsonResponse({'code':200}) #修改头像 @logging_check def users_views(request,username): if request.method != 'POST': result = {'code':201,'error':'请求方式并非post'} return JsonResponse(result) # try: # user = UserProfile.objects.get(username=username) # except Exception as e: # result = {'code':208, 'error':'用户名不存在'} # return JsonResponse(result) user = request.myuser avatar = request.FILES['avatar'] user.avatar = avatar user.save() return JsonResponse({'code':200})

浙公网安备 33010602011771号