多人博客项目构建过程(二)

用户功能设计与实现

用户登录接口设计

{    
  "password":"test",
  "email":"[email protected]"          
}

路由配置

#在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

猜你喜欢

转载自www.cnblogs.com/xiaoshayu520ly/p/11427173.html