10Django-自定義驗證使用者登入裝飾器並將裝飾器應用到使用者更新操作的檢視中
阿新 • • 發佈:2021-12-13
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 importsettings 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})