美文网首页
59.1-Django认证、中间件和jwt过期

59.1-Django认证、中间件和jwt过期

作者: BeautifulSoulpy | 来源:发表于2020-08-16 16:05 被阅读0次
人生,方向比努力更重要。学会忘掉过去,过去再美再辉煌,终究代表的是过去的自己!

总结:

  1. 框架其实就是 流程、套路;
logininfo
1. Django的认证

django.contrib.auth中提供了许多方法,这里主要介绍其中的三个:
1、authenticate(**credentials)
提供了用户认证,即验证用户名以及密码是否正确
user = authentica(username='someone',password='somepassword')
2、login(HttpRequest, user, backend=None)
该函数接受一个HttpRequest对象,以及一个认证了的User对象
此函数使用django的session框架给某个已认证的用户附加上session id等信息。
3、logout(request) 本次使用
注销用户
该函数接受一个HttpRequest对象,无返回值。
当调用该函数时,当前请求的session信息会全部清除
该用户即使没有登录,使用该函数也不会报错
还提供了一个装饰器来判断是否登录django.contrib.auth.decorators.login_required
本项目使用了无session机制,且用户信息自己建表管理,所以,认证需要自己实现。

2. 中间件技术Middleware

官方定义,在Django的request和response处理过程中,由框架提供的hook钩子
中间件技术在1.10后发生了改变,我们当前使用1.11版本,可以使用新的方式定义。
参看 https://docs.djangoproject.com/en/1.11/topics/http/middleware/#writing-your-own-middleware

# 要在setting的MIDDLEWARE中注册;
class AuthMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # One-time configuration and initialization.

    def __call__(self, request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.
        print(request,'++++++++++++++++++++++++++')
        token = request.META.get('HTTP_JWT',None)
        print(token)
        # 统计IP验证 : 1分钟1000次以上;  使用字典记录次数 =》 redis kv; 调shell - 防火墙;


        response = self.get_response(request)

        # Code to be executed for each request/response after
        # the view is called.

        return response

但是, 这样所有的请求和响应都拦截, 我们还得判断是不是访问的想要拦截的view函数, 所以, 考虑其他方法。
中间件有很多用途, 适合拦截所有请求和响应。例如 浏览器端的IP是否禁用、UserAgent分析、异常响应的统一处理。

3. 装饰器*

在需要认证的view函数上增强认证功能,写一个装饰器函数。谁需要认证,就在这个view函数上应用这个装饰器。

AUTH_EXPIRE = 8 * 60 * 60  # 8小时过期

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', -1)
            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)  # 调用视图函数
        # 特别注意view调用的时候,里面也有返回异常
        return ret
    return wrapper

@authenticate  # 很自由的应用在需要认证的view函数上
def test(request: HttpRequest):
    return HttpResponse('test')
from django.http import JsonResponse,HttpRequest,HttpResponseBadRequest
import simplejson,jwt,bcrypt,datetime
from .models import User
from django.db.models import Q
from django.conf import settings

AUTH_EXPIRE = 8*60*60

def gen_token(user_id):  # 生成令牌;
    key = settings.SECRET_KEY
    return jwt.encode({'user_id':user_id,
                       'timestamp':int(datetime.datetime.now().timestamp() + AUTH_EXPIRE)  # 结束时间
                       },key,'HS256').decode()

# register
def reg(request:HttpRequest):
    print(request.body)

    try:
        payload = simplejson.loads(request.body)  # 用户数据Json化 提交;
        print(type(settings))

        email = payload['email']      # 提取内容
        query = User.objects.filter(email=email)   # 看email是否已经存在;
        if query.first():  # 查一下: email 如果存在,则return error;
            print('============================')
            return HttpResponseBadRequest('用户名已存在')

        # 用户名不存在,继续向下;
        name = payload['name']   #
        password = payload['password']

        user = User()
        user.email = email
        user.name = name
        user.password = bcrypt.hashpw(password.encode(),bcrypt.gensalt())   # 密码采用bcrypt加密;盐一直在变,强加密;

        try:
            user.save()    #保存到数据库test,唯一键约束
            return JsonResponse({
                'user_id':user.id
            })   # 保存数据后返回一个令牌数据回去;
        # 可以返回user_id status=201(注册成功 重新登录) 或者 token(登录)

        except Exception as e:
            return JsonResponse({'reason':'asdaf'},status=400)
    except Exception as e:
        print(e)
        return HttpResponseBadRequest('参数错误')


def login(request:HttpRequest):
    try:
        payload = simplejson.loads(request.body)
        email = payload['email']
        password = payload['password']

        user = User.objects.filter(email=email).first()
        if user:  # 登录成功,返回信息
            if bcrypt.checkpw(password.encode(),user.password.encode()):
                token = gen_token(user.id)
                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('登录失败3')
        else:
            return HttpResponseBadRequest('登录失败1')

    except Exception as e:   # 记录登录日志;
        print(e)
        return HttpResponseBadRequest('登录失败2')

# 谁认证就给谁加装饰器;
def auth(view_func):
    def wrapper(request:HttpRequest):
        token = request.META.get('HTTP_JWT', None)  # 拿到http_jwt 字典的值
        # print(list(filter(lambda x: x.lower().endswith('jwt'),meta)))  #查询 http_jwt
        print(token)
        if not token: #  认证失败
            return HttpResponseBadRequest()

        key = settings.SECRET_KEY
        try:
            print('=============================')
            payload = jwt.decode(token, key, algorithms=['HS256'])  # 解失败,被改过;接成功;没改过;
            # dt = payload['timestamp']
            # current = datetime.datetime.now().timestamp()
            #
            # if (current - dy) > AUTH_EXPIRE:    # exp check 过期检查;
            #     return HttpResponseBadRequest('expire')
            # user_id = payload.get('user_id',-1)
            user = User.objects.filter(pk=payload['user_id']).first()   # 查询一次数据库;
            # user = User.objects.filter(pk=payload['user_id']).filter(isactive=True).first()

            if user: # 拿到user,
                request.user = user  #request 动态添加属性;
                ret = view_func(request)

                return ret
            else:
                return HttpResponseBadRequest('1用户名密码错误')
        except jwt.ExpiredSignatureError as e:
            print(e)
            return HttpResponseBadRequest('jwt过期')
        except Exception as e:
            print(e)
            return HttpResponseBadRequest('用户名密码错误')
    return wrapper

@auth        # 认证拦截
def show(request):          # 方法的使用方式各不相同;
    # print(request.user,'---------------------------')
    return JsonResponse({'status':'ok'})

# 要在setting的MIDDLEWARE中注册;
class AuthMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # One-time configuration and initialization.

    def __call__(self, request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.
        print(request,'++++++++++++++++++++++++++')
        token = request.META.get('HTTP_JWT',None)
        print(token)
        # 统计IP验证 : 1分钟1000次以上;  使用字典记录次数 =》 redis kv; 调shell - 防火墙;


        response = self.get_response(request)

        # Code to be executed for each request/response after
        # the view is called.

        return response

相关文章

  • 59.1-Django认证、中间件和jwt过期

    人生,方向比努力更重要。学会忘掉过去,过去再美再辉煌,终究代表的是过去的自己! 总结:框架其实就是 流程、套路; ...

  • oc 解析jwt

    oc 解析jwt 和过期时间计算

  • JWT认证原理分析

    基于session的认证 JWT认证规则 JWT(Json Web Token) JWT原理 签发算法 校验算法 ...

  • jwt、session、oauth 异同

    1,jwt 和session机制 首先jwt 和session机制 都是用户认证的,oauth 不是 sessio...

  • JWT

    JWT | 简介 全称:JSON Web Token; JWT 主要用于身份认证和信息加密; JWT 是一个简单而...

  • .NET Core5.0 JWT鉴权SSO单点登录

    JWT JWT全称“JSON Web Token”,是基于JSON的用户身份认证的令牌。可跨域身份认证,所以JWT...

  • JWT

    iss: jwt签发者 sub: jwt所面向的用户 aud: 接收jwt的一方 exp: jwt的过期时间,这个...

  • 带你了解JWT

    @TOC 什么是JWT 认证方式 在JWT之前,我们用过Sssion来进行认证,也使用过Token认证。那么这两种...

  • 从零搭建个人博客(四)-集成jwt

    为什么使用 JWT 集成 jwt 生成 token 编写 Auth 中间件 在接口中进行拦截 使用 koa-jwt...

  • 09使用 Go 添加 JWT 认证

    介绍 jwt 实践定义功能签发接口验证中间件使用 总结 当前部分的代码 在典型的业务场景中, 认证与鉴权是十分基础...

网友评论

      本文标题:59.1-Django认证、中间件和jwt过期

      本文链接:https://www.haomeiwen.com/subject/hcbtjktx.html