1、优化后的登陆接口

  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”)

  1. if email and nick and phone and password:
  2. if password != password2:
  3. return JsonResponse({"code": -1, "msg": "两次输入的密码不一致"})
  4. user_email = models.NewUser.objects.filter(email=email)
  5. user_phone = models.NewUser.objects.filter(phone=phone)
  6. if user_email.exists():
  7. return JsonResponse({"code": -1, "msg": "email exists"})
  8. if user_phone.exists():
  9. return JsonResponse({"code": -1, "msg": "phone exists"})
  10. new_password = md5(password)
  11. user = models.NewUser(email=email, nick=nick, phone=phone, password=new_password)
  12. user.save()
  13. return JsonResponse({"code": 0, "msg": "success"})
  14. else:
  15. 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”})

  1. #todo:这里要校验当前用户是否已经登录,如果已经登录,那么直接返回token (用来解决重复登陆存储多个token的问题)
  2. user_key = "session_wxj:%s"%user.first().phone
  3. # 登陆时,给Redis中存储两条记录 (用户名:token)(token:用户信息)
  4. #
  5. r = django_redis.get_redis_connection()
  6. redis_token = r.get(user_key)
  7. if redis_token:# 如果Redis中有这个用户的登陆记录就返回上一次登陆获取的token
  8. return JsonResponse({"code": 0, "msg": "login success", "token": redis_token.decode()})
  9. #
  10. token = md5(str(time.time()) + username) # 如果没有登陆记录,就重新返回新的token
  11. # user_dict = json.dumps(model_to_dict(user.first())) # 被优化的代码
  12. pickle_user_obj = pickle.dumps(user.first()) # 优化的代码:直接把 模型类的实例对象 以二进制对象 存入变量中
  13. r = django_redis.get_redis_connection()
  14. expire_time = 60 * 60 * 24 * 1 # session的过期时间
  15. #
  16. r.set(user_key, token, expire_time)# 登陆时,给Redis中存储两条记录 (用户名:token)(token:用户信息)
  17. #
  18. # r.set(token, user_dict, expire_time) # 被优化的代码
  19. r.set(token,pickle_user_obj,expire_time) # 优化的代码:直接 模型类的实例对象 以二进制形式存入Redis中
  20. return JsonResponse({"code": 0, "msg": "login success", "token": token})
  21. else:
  22. return JsonResponse({"code": -1, "msg": "not null"})

def md5(s): s = str(s) m = hashlib.md5(s.encode()) return m.hexdigest()

  1. <a name="H0M66"></a>
  2. # 2、优化后的中间件
  3. - 将登陆后,Redis中的用户信息,通过pickle再次用request对象的自定义属性去接收
  4. ```python
  5. import pickle
  6. from django.middleware.common import MiddlewareMixin
  7. from django.http.response import HttpResponse, JsonResponse
  8. import django_redis
  9. import json
  10. no_login_urls = ["login", "register", "admin"]
  11. class TokenMiddleWare(MiddlewareMixin):
  12. def check_not_url(self, path): # /api/login
  13. for url in no_login_urls:
  14. if url in path:
  15. # 模糊匹配,URL中包含这个就不校验token
  16. return True
  17. def process_request(self, request):
  18. # 执行路由之前被调用
  19. login_tag = self.check_not_url(request.path_info)
  20. if login_tag != True:
  21. token = request.GET.get("token")
  22. if not token:
  23. return JsonResponse({"code": -1, "msg": "没有传token"})
  24. r = django_redis.get_redis_connection()
  25. login_user = r.get(token)
  26. if not login_user:
  27. return JsonResponse({"code": -1, "msg": "token已失效"})
  28. # request.user = json.loads(login_user) # 给request对象里面增加user属性
  29. request.user = pickle.loads(login_user) # 优化后:request对象的user属性 就是 模型类的实例对象了,
  30. # 可以从这个对象身上查到用户所有信息
  31. # token = reuqest.headers.get("token")
  32. # request.path_info /login /api/register
  33. # 1、先判断url是否需要登录,需要登录才校验token
  34. # 2、在判断是否传了token
  35. # 3、再判断在redis里面是否有token
  36. # def process_response(self,request,response):
  37. # print("process_response")
  38. # response["aaaaa"] = "111111"
  39. # return response
  40. # def process_exception(self,request,exception):
  41. # print("exception",exception)
  42. # return