1、优化后的登陆接口
- 利用pickle模块可以直接读写对象的特性,将从数据库中查到的用户对象直接存入Redis中 ```python import hashlib import json import pickle import time
import django_redis from django.forms import model_to_dict from django.http import JsonResponse from django.db.models import Q from django.shortcuts import render from . import models
Create your views here.
注册接口
def register(request): email = request.POST.get(“email”) nick = request.POST.get(“nick”) phone = request.POST.get(“phone”) password = request.POST.get(“password”) password2 = request.POST.get(“password2”)
if email and nick and phone and password:if password != password2:return JsonResponse({"code": -1, "msg": "两次输入的密码不一致"})user_email = models.NewUser.objects.filter(email=email)user_phone = models.NewUser.objects.filter(phone=phone)if user_email.exists():return JsonResponse({"code": -1, "msg": "email exists"})if user_phone.exists():return JsonResponse({"code": -1, "msg": "phone exists"})new_password = md5(password)user = models.NewUser(email=email, nick=nick, phone=phone, password=new_password)user.save()return JsonResponse({"code": 0, "msg": "success"})else:return JsonResponse({"code": -1, "msg": "not null"})
优化后的登陆接口
def login2(request): username = request.POST.get(“username”) # email + password ; phone+password password = request.POST.get(“password”) if username and password: user = models.NewUser.objects.filter(Q(email=username) | Q(phone=username)) if not user.exists(): return JsonResponse({“code”: -1, “msg”: “user not exists”}) if user.first().password != md5(password): return JsonResponse({“code”: -1, “msg”: “password error”})
#todo:这里要校验当前用户是否已经登录,如果已经登录,那么直接返回token (用来解决重复登陆存储多个token的问题)user_key = "session_wxj:%s"%user.first().phone# 登陆时,给Redis中存储两条记录 (用户名:token)(token:用户信息)#r = django_redis.get_redis_connection()redis_token = r.get(user_key)if redis_token:# 如果Redis中有这个用户的登陆记录就返回上一次登陆获取的tokenreturn JsonResponse({"code": 0, "msg": "login success", "token": redis_token.decode()})#token = md5(str(time.time()) + username) # 如果没有登陆记录,就重新返回新的token# user_dict = json.dumps(model_to_dict(user.first())) # 被优化的代码pickle_user_obj = pickle.dumps(user.first()) # 优化的代码:直接把 模型类的实例对象 以二进制对象 存入变量中r = django_redis.get_redis_connection()expire_time = 60 * 60 * 24 * 1 # session的过期时间#r.set(user_key, token, expire_time)# 登陆时,给Redis中存储两条记录 (用户名:token)(token:用户信息)## r.set(token, user_dict, expire_time) # 被优化的代码r.set(token,pickle_user_obj,expire_time) # 优化的代码:直接 模型类的实例对象 以二进制形式存入Redis中return JsonResponse({"code": 0, "msg": "login success", "token": token})else:return JsonResponse({"code": -1, "msg": "not null"})
def md5(s): s = str(s) m = hashlib.md5(s.encode()) return m.hexdigest()
<a name="H0M66"></a># 2、优化后的中间件- 将登陆后,Redis中的用户信息,通过pickle再次用request对象的自定义属性去接收```pythonimport picklefrom django.middleware.common import MiddlewareMixinfrom django.http.response import HttpResponse, JsonResponseimport django_redisimport jsonno_login_urls = ["login", "register", "admin"]class TokenMiddleWare(MiddlewareMixin):def check_not_url(self, path): # /api/loginfor url in no_login_urls:if url in path:# 模糊匹配,URL中包含这个就不校验tokenreturn Truedef process_request(self, request):# 执行路由之前被调用login_tag = self.check_not_url(request.path_info)if login_tag != True:token = request.GET.get("token")if not token:return JsonResponse({"code": -1, "msg": "没有传token"})r = django_redis.get_redis_connection()login_user = r.get(token)if not login_user:return JsonResponse({"code": -1, "msg": "token已失效"})# request.user = json.loads(login_user) # 给request对象里面增加user属性request.user = pickle.loads(login_user) # 优化后:request对象的user属性 就是 模型类的实例对象了,# 可以从这个对象身上查到用户所有信息# token = reuqest.headers.get("token")# request.path_info /login /api/register# 1、先判断url是否需要登录,需要登录才校验token# 2、在判断是否传了token# 3、再判断在redis里面是否有token# def process_response(self,request,response):# print("process_response")# response["aaaaa"] = "111111"# return response# def process_exception(self,request,exception):# print("exception",exception)# return
