Django上自建一个token校验机制

场景介绍

自己开发的接口有些需要实名认证,不能直接让匿名用户访问,那如果使用django的login_require装饰器设置在接口方法前面 会直接返回登录页面,所以在这个时候,可以考虑自己开发一个验证机制了,防止匿名用户调用。

验证流程

  1. 先让用户提交用户密码到获取token的接口
  2. 拿到用户名密码后去后台验证是否有效,如果有效就判断这个用户是否有token在数据库中,有的话就更新这个token,否则就新建一条记录在数据库,然后返回这个新建好的token的给请求者。
  3. 用户拿到刚才请求到的token后,在请求头或者请求参数里面携带这个token。然后再去请求对应的接口。
  4. 请求过来以后,首先自建的验证机制会对token进行校验,去请求参数里面找,参数也没有就返回校验失败,找到token以后就去判断这个token是否存在和过期,token无效、过期的话,返回校验失败,只有校验成功以后,才会放行请求到接口上,此时接口才会真正处理用户的请求。

需要做的事

  1. 新建一个表
  2. 新建一个创建token的方法
  3. 新建一个校验token的装饰器
  4. 接口上使用装饰器即可

以上在你的项目中一个models和views编写即可,编写完以后,哪里需要使用,导入这个装饰器即可。

实操步骤

以下都运行在python3.5.6 和 django 1.11.13 上,无问题。

创建数据库
from django.db import models

# Create your models here.
from pisces import settings
from datetime import timedelta,datetime
from django.contrib.auth.models import User
import pytz
import random
#tzutc_8=pytz.FixedOffset(480)
#tzutc_8=pytz.timezone("UTC")
tzutc_8=pytz.timezone(‘Asia/Shanghai‘)

class user_token(models.Model):
    user = models.OneToOneField(User,related_name=‘user_profile‘)
    utype = models.CharField(max_length=15, default="guest") # ?????? guest access admin
    utoken = models.CharField(max_length=256, null=True,blank=True)
    utokenCreateTime = models.DateTimeField(null=True,blank=True)
    utokenExpire = models.DateTimeField(null=True,blank=True)

    def getRandomChar(self,start=None,end=None,length=30):
        ‘‘‘
        get a random int and then translate to char
        :param start:
        :param end:
        :param length:
        :return:  return a token
        ‘‘‘
        if ( start and not start.isdigit() ) or not start:
            start = 65
        if ( end and not end.isdigit() ) or not end:
            end = 122
        randomChar = ""
        for i in range(length):
            x = random.randint(start,end)
            # >>> chr(91)
            # ‘[‘
            # >>> chr(92)
            # ‘\\‘
            # >>> chr(93)
            # ‘]‘
            # >>> chr(94)
            # ‘^‘
            # >>> chr(95)
            # ‘_‘
            # >>> chr(96)
            # ‘`‘

            if x == 91 or x == 92 or x == 93 or x == 94 or x == 95 or x == 96:
                continue
            randomChar = randomChar + chr(x)
        return randomChar

    def updateToken(self):
        ‘‘‘
        update the user‘s token ,if the token is exist,it will be update ,else the token is not exist,it will be create
        :return:
        ‘‘‘
        utokenDuration = settings.UTOKEN_DURATION
        if self.utokenCreateTime:  # means it has created,
            if not  self.utokenExpire:
                self.utokenExpire = datetime.now() + timedelta(seconds=utokenDuration)
                self.save()
            differenceTime = self.utokenExpire - self.utokenCreateTime
            if differenceTime.seconds - utokenDuration <= 60: # update the token before 1 min
                randomChar = self.getRandomChar()
                self.utoken = randomChar
                self.utokenExpire = datetime.now()   + timedelta(seconds=utokenDuration)
                self.save()
                return {"code":200,"msg":"update utoken successfully!"}
            else:
                return {"code":301,"msg":"the utoken is not expire!so won‘t update! "}
        else:
            randomChar = self.getRandomChar()
            self.utoken = randomChar
            self.utokenCreateTime = datetime.now()
            self.utokenExpire = datetime.now()  + timedelta(seconds=utokenDuration)
            self.save()
            return {"code":200,"msg":"create utoken successfully!"}

    def checkUtokenIsValid(self,utoken):
        ‘‘‘
        check the utoken weather is valid or not!
        :return:
        ‘‘‘
        if self.utokenCreateTime and self.utokenExpire:  # means it has created,
            #print(self.utokenCreateTime.astimezone(tzutc_8),  self.utokenCreateTime, datetime.now())
            if self.utokenExpire.astimezone(tzutc_8) <=  pytz.utc.localize(datetime.now()): # update the token before 1 min
                return {"code":400,"msg":"the utoken was expire! please update it! exipre time:%s , system time:%s"%(self.utokenExpire.astimezone(tzutc_8).strftime("%Y-%m-%d %H:%M:%S"),pytz.utc.localize(datetime.now()))}
            else:
                if utoken == self.utoken:
                    return {"code":200,"msg":"correct"}
                else:
                    return {"code":401,"msg":"not correct"}
        else:
            return {"code":400,"msg":"the utoken is not create! please authenticate! "}

    def __str__(self):
        return "%s-%s"%(self.user.username,self.utype)

编写装饰器与创建token的方法
创建token的方法
from django.shortcuts import render,redirect
from django.contrib.auth import authenticate
from django.contrib.auth.models import User
from center.models import user_token
from django.http import JsonResponse
from django.contrib.auth import login as auth_login, logout as auth_logout
from django.views.decorators.csrf import csrf_exempt
from pisces.mylog import writeDebug,writeInfo,writeErr

@csrf_exempt
def get_utoken(request):
    ‘‘‘
    get the user‘s token
    :param request:
    :return:
    ‘‘‘
    if request.method == ‘POST‘:
        username = request.POST.get(‘username‘, ‘‘)
        password = request.POST.get(‘password‘, ‘‘)
        user = authenticate(username=username, password=password)
        if user:
            writeDebug("center/views","get_utoken","the user[%s] login successfully"%username)
            auth_login(request, user, )
            userObj = User.objects.filter(username=username)
            if not userObj:
                writeDebug("center/views","get_utoken","no userObj[%s],begin to create the user"%username)
                ux = User.objects.create_user(username,"%[email protected]"%username,password)
                utk = user_token(user=ux)
                utk.save()
                utkobj = user_token.objects.filter(user=ux).first()
                updateTokenMsg = utkobj.updateToken()
                utoken = utkobj.utoken
            else:
                utkobj = user_token.objects.filter(user=userObj)
                if not utkobj:
                    utkobj_save = user_token(user=userObj.first())
                    utkobj_save.save()
                    #utkObj = user_token.objects.filter(user=userObj)
                updateTokenMsg = utkobj.first().updateToken()
                utkobj.first().save()

                utoken = utkobj.first().utoken
            writeInfo("frame/views","login","the username[ {username} ] login and create token successfully!".format(username=username))
            return JsonResponse({"utoken":utoken,"code":200,"msg":updateTokenMsg.get("msg")})
        writeInfo("frame/views","login","the username[ {username} ] or password is invalied,can‘t login!".format(username=username))
        return JsonResponse({"code":401,"msg":"the username or password is not correct!"})
    else:
        return JsonResponse({"code":402,"msg":"only post method is support"})
校验token的装饰器
from django.shortcuts import render,redirect
from django.contrib.auth import authenticate
from django.contrib.auth.models import User
from center.models import user_token
from django.http import JsonResponse
from django.contrib.auth import login as auth_login, logout as auth_logout
from django.views.decorators.csrf import csrf_exempt
from pisces.mylog import writeDebug,writeInfo,writeErr
def checkUserToken(func):
    ‘‘‘
    check if the user has the token
    :param func:
    :return:
    ‘‘‘
    def warper(*args,**kwargs):
        try:
            utoken = args[0].POST.get("utoken")
            if utoken is None:
                utoken = args[0].GET.get("utoken")
        except BaseException as e:
            try:
                utoken = args[0].GET.get("utoken")
            except BaseException as e:
                return JsonResponse({"code":400,"msg":"can‘t get utoken! please check params"})

        if not utoken:
            return JsonResponse({"code":400,"msg":"can‘t get utoken! please check params"})

        userObj = user_token.objects.filter(utoken=utoken)
        if userObj:
            ux = userObj.first()
            result = ux.checkUtokenIsValid(utoken)
            if result.get("code") == 200:
                kwargs[‘username‘] = ux.user.username
                return func(*args,**kwargs)
            else:
                return JsonResponse(result)
        else:
            return JsonResponse({"code":404,"msg":"can‘t find the user by utoken--> %s"%(utoken)})
    return warper

使用装饰器


from center.views import checkUserToken
from django.http.response import JsonResponse

@checkUserToken
@csrf_exempt
def create_zk_with_zkjob(request):
    ‘‘‘

    :param request:
    :return:
    ‘‘‘
    // 请求参数该怎么获取就怎么获取,并没有改变参数的获取方式
    // 以下替换成你的逻辑代码即可。
    post_env = request.POST.get("env")
    post_cxxx = request.POST.get("cxxx")
    post_project_name = request.POST.get("project_enname")
    zkop = core.zkopreation(post_env)
    zknodename = "%s%s_%s/foo"%(zkop.zkRootPath,post_cxxx,post_project_name)
    zkop_result = zkop.createPath(zknodename)
    return JsonResponse(zkop_result)

原文地址:https://www.cnblogs.com/liaojiafa/p/12547584.html

时间: 2024-10-06 23:09:06

Django上自建一个token校验机制的相关文章

django局域网建一个网站

之前总是运行的python manage.py runserver,用默认的在本机访问的127.0.0.1:8000,如果跟几个同学一起去开发一个网站来玩玩的话,可以这样: python manage.py runserver (your ip):(your port),指定你的ip和port,则局域网内其他客户端可以访问这个django建的网站了. django局域网建一个网站,布布扣,bubuko.com

教你怎样在电脑上建一个绝密目录

电脑中总有一些私密文件或者公司客户关键文件不想让别人看到或者窃取篡改,怎样建立一个别人都打不开的目录,简单几招请往下看! 1.在e盘中,建一个命名为"绝密文件"的目录为样例. 2.快捷键win+R高速打开执行窗体.输入"cmd",点击确定.进入cmd执行模式,在光标后面输入"attrib +s +a +h +r e:绝密文件"(注意中间留有空格.且都是英文输入状态). 然后点击回车键,例如以下图所看到的将会成功执行. 3.这时我们又一次打开e盘.

drf框架 8 系统权限类使用 用户中心信息自查 token刷新机制 认证组件项目使用:多方式登录 权限组件项目使用:vip用户权限 频率组件 异常组件项目使用

系统权限类使用 图书接口:游客只读,用户可增删改查权限使用 from rest_framework.permissions import IsAuthenticatedOrReadOnly class BookViewSet(ModelViewSet): # 游客只读,用户可增删改查 permission_classes = [IsAuthenticatedOrReadOnly] queryset = models.Book.objects.all() serializer_class = se

《快速创建网站》2.1 在Azure上创建网站及网站运行机制

现在让我们开始一天的建站之旅. 本文是<快速创建网站>系列的第2篇,如果你还没有看过之前的内容,建议你点击以下目录中的章节先阅读其他内容再回到本文. 1. 网站管理平台WordPress和云计算平台Azure简介2.1 在Azure上创建网站及网站运行机制2.2 域名绑定操作和Azure负载均衡机制2.3 WordPress 初始化和网站管理功能3.1 WordPress 数据导入3.2 WordPress 多站点支持和Azure在线代码编辑器3.3 WordPress 多语言支持 Multi

java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessController的checkPerssiom方法,访问控制器AccessController的栈检查机制又遍历整个 PerssiomCollection来判断具体拥有什么权限一旦发现栈中一个权限不允许的时候抛出异常否则简单的返回,这个过程实际上比我的描述要复杂 得多,这里我只是简单的一句带过,因为这

java jvm学习笔记十二(访问控制器的栈校验机制)

欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 本节源码:http://download.csdn.net/detail/yfqnihao/4863854 这一节,我们会简单的描述一下jvm访问控制器的栈校验机制. 这节课,我们还是以实践为主,什么是栈校验机制,讲一百遍不如你自己实际的代码一下然后验证一下,下面我们下把环境搭起来. 第一步,配置系统环境.(copy吧,少年) path=%JAVA_HOME%/bin JAVA_HOME=C:/Java/jdk1.6

token验证机制

最近在vue-cli项目实现登录的过程中用到了token验证,在此总结如下 1. 登录时,客户端通过用户名与密码请求登录 2. 服务端收到请求去验证用户名与密码 3. 验证通过,服务端会签发一个Token,再把这个Token以响应发给客户端. 4. 客户端收到Token,存储到本地,如Cookie,SessionStorage,LocalStorage.我们是存在cookie 5. 客户端每次像服务器请求API接口时候,都要带上Token. 6. 客户端每次跳转路由的时候也要验证Token登录态

django上传文件

django上传文件 template html(模板文件): <form enctype="multipart/form-data" method="POST" action="/address/upload/"> <input type="file" name="file" /> <br /> <input type="submit" val

直播 linux上的第一个c++程序

这里用crt来直播吧: 登录到服务器上之后: 1.mkdir -p 建一个文件夹 2.ll 查看一下这个文件夹 3.cd 进入这个文件夹 4.vim 进行文本编辑 写完之后,按下esc中止输入模式,用:wq强制保存并退出. 使用g++编译生成可运行的first文件,然后运行它,最终输出 hello word!