用户功能设计与实现
用户登录接口设计
{ "password":"test", "email":"test@magedu.com" }
路由配置
#在user/urls.py文件中 from django.conf.urls import url from .views import reg,login urlpatterns = [ url(r'^reg$',reg), url(r'^login$',login) ]
登录代码
def login(request:HttpRequest): payload = simplejson.loads(request.body) try: email = payload['email'] password = payload['password'].encode() user = User.objects.filter(email=email).get() if bcrypt.checkpw(password,user.password.encode()):#user.password代表数据库里面的密码 #验证通过 token = gen_token(user.id) # print(token) res = JsonResponse({ 'user':{ 'user_id':user.id, 'name':user.name, 'email':user.email }, 'token':token }) res.set_cookie('Jwt',token)#演示如何设置set cookie return res else: return HttpResponseBadRequest() except Exception as e: print(e) return HttpResponseBadRequest()#这里返回实例,这不是异常类
认证接口
Django的认证
中间件技术Middleware
class BlogAuthMiddleware(object): """自定义中间件""" def __init__(self,get_response): self.get_response = get_response def __call__(self, request:HttpRequest): #视图函数之前执行 #认证 print(type(request),'~~~~') print(request.GET) print(request.POST) print(request.body)#json数据 response = self.get_response(request) #试图函数之后执行 #TODO return response #要在settings的MIDDLEWARE中注册
装饰器*
#user/urls.py from django.conf.urls import url from .views import reg,login,test#,testMiddle urlpatterns = [ url(r'^test',test), ]
#user/views.py AUTH_EXPIRE = 8*60*60 def authenticate(view): def wrapper(request:HttpRequest): #自定义header jwt payload = request.META.get('HTTP_JWT')#会加前缀HTTP_且全大写 if not payload:#None没有拿到,认证失败 return HttpResponse(status=401) try:#解码 payload = jwt.decode(payload,settings.SECRET_KEY,algorithms=['HS256']) print(payload) except: return HttpResponse(status=401) #验证过期时间 current = datetime.datetime.now().timestamp() if (current - payload.get('timestamp',0)) > AUTH_EXPIRE: return HttpResponse(status=401) print('*'*30) try: user_id = payload.get('user_id') user = User.objects.filter(pk=user_id).get() request.user = user print('*'*30) except Exception as e: print(e) return HttpResponse(status=401) ret = view(request)#调用视图函数 return ret return wrapper @authenticate def test(request:HttpRequest):#很自由的应用在需要认证的view函数上 return HttpResponse('test')
JWT过期问题
import jwt import datetime import threading event = threading.Event() key = 'magedu' data = jwt.encode({'name':'tom','age':20,'exp':int(datetime.datetime.now().timestamp()+3)},key) print(jwt.get_unverified_header(data)) try: while not event.wait(1): print(jwt.decode(data,key))#过期,校验会抛出异常 print(datetime.datetime.now().timestamp()) except jwt.ExpiredSignatureError as e: print(e)
#user.views.py AUTH_EXPIRE = 8*60*60 # def gen_token(user_id): """生成token""" return jwt.encode({#增加时间戳,判断是否重发token或重新登录 'user_id':user_id, 'exp':int(datetime.datetime.now().timestamp() + 500)#需要取整 },settings.SECRET_KEY,'HS256').decode() #字符串 def authenticate(view): def wrapper(request:HttpRequest): #自定义header jwt payload = request.META.get('HTTP_JWT')#会加前缀HTTP_且全大写 print(payload,'#'*10) if not payload:#None没有拿到,认证失败 return HttpResponse(status=401) try:#解码 payload = jwt.decode(payload,settings.SECRET_KEY,algorithms=['HS256']) print(payload) except: return HttpResponse(status=401) try: user_id = payload.get('user_id') user = User.objects.filter(pk=user_id).get() request.user = user#如果正确则注入user print('*'*30) except Exception as e: print(e) return HttpResponse(status=401) ret = view(request)#调用视图函数 return ret return wrapper