极验验证demo(django+vue) 原

在使用之前,曾经试过用云的人机验证,不过在签名部分比较复杂,下载sdk后需要自己写很多,折腾了一下,还是放弃。而腾讯云的人机验证python版本有demo,直接填写keyhe1secret就可以使用,但是demo使用的是web.py的框架,这个之前有了解过,比较好用,但是作者去世了,只有python2版本,没有3的版本,想了一下即使修改成3的版本,还要做改成django的,有点麻烦。网易云的宣传上有vue版本的,而且效果看起来不错,本来想试一下,但是注册后还要官方通过验证,等了1天还没通过,就打算另找方法。

偶然翻看博客,发现有人介绍geetest,看了一下感觉上手比较容易,sui遂注册使用。

一、简单注册使用

geetest官网:https://www.geetest.com/

该公司主要是做验证的。目前开放的是行为验证。身份验证还未开放。

注册申请后,获得id和key。在其github项目上下载相应语言和版本,就可使用。

文档看起来也比较清晰

老版本python sdk下载:https://github.com/GeeTeam/gt-python-sdk

新版本python sdk下载:https://github.com/GeeTeam/gt3-python-sdk

这两个都可以使用python2.7以上的版本,区别在于验证特性设置有些不同。需要注意的是django版本是1.8

根据之前项目的django是1.11.3版本,修改了sdk中报错的部分代码。

下载之后运行setup.py文件

在demo中发现python的三大主流框架都有,这真是太棒了呢

在django_demo文件夹中先安装requirements.txt里面需要的库

注意:打开django_demo下的settings.py文件

TEMPLATE_DIRS = (
    os.path.join(BASE_DIR, "static"),
)

最后添加这部分,官方的内容给的是绝对路径,我们需要拼接相对路径

demo中的文件替换自己项目中相应的文件

运行后即可看到验证页面

二、vue和python部分结合

分析:后端中validate和ajax_validate区别是:返回页面与返回数据

鉴于我们使用前后端分离的方式,在提交路径上选择ajax_validate

1.vue部分

(1)form-action属性提交

python部分可用后,打开demo中的index.html,将html部分放置在vue验证组件的template中,将style放在vue的style中。

在根页面的head区域引入jquery

<script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script>

打开http://static.geetest.com/static/tools/gt.js复制全部内容到你的assets资源目录下

在你的验证组件页面引入刚才复制的资源

import '../assets/js/gt.js'

在methods里新建一个方法

拷贝demo.html中script里ajax获取数据的方法,在vue里改为axios获取

    getCaptchaData () {
      this.$axios.get('/api/register?t=' + (new Date()).getTime())
        .then((res) => {
          console.log('res', res)
          var handlerEmbed = function (captchaObj) {
            $('#embed-submit').click(function (e) {
              var validate = captchaObj.getValidate()
              if (!validate) {
                $('#notice')[0].className = 'show'
                setTimeout(function () {
                  $('#notice')[0].className = 'hide'
                }, 2000)
                e.preventDefault()
              }
            })
            // 将验证码加到id为captcha的元素里
            captchaObj.appendTo('#embed-captcha')
            captchaObj.onReady(function () {
              $('#wait')[0].className = 'hide'
            })
          // 更多接口参考:http://www.geetest.com/install/sections/idx-client-sdk.html
          }
          // 使用initGeetest接口
          // 参数1:配置参数
          // 参数2:回调,回调的第一个参数验证码对象,之后可以使用它做appendTo之类的事件
          window.initGeetest({
            gt: res.data.gt,
            challenge: res.data.challenge,
            product: 'embed', // 产品形式,包括:float,embed,popup。注意只对PC版验证码有效
            offline: !res.data.success // 表示用户后台检测极验服务器是否宕机,一般不需要关注
          }, handlerEmbed)
        })
        .catch(function (error) {
          console.log(error)
        })
    }

在创建时启动

    this.getCaptchaData()

附件:slidingBlock1.vue

<!-- slidingBlock1:form-action部分 -->
<template>
<form class="popup" action="http://127.0.0.1:8000/api/ajax_validate" method="post">
    <p>
      <label for="user">用户名:</label>
      <input class="inp" id="user" type="text" value="极验验证">
    </p>
    <br>
    <p>
      <label for="password">密&nbsp;&nbsp;&nbsp;&nbsp;码:</label>
      <input class="inp" id="password" type="password" value="123456">
    </p>
    <div id="embed-captcha"></div>
    <p id="wait" class="show">正在加载验证码......</p>
    <p id="notice" class="hide">请先拖动验证码到相应位置</p>
    <br>
    <input class="btn" id="embed-submit" type="submit" value="提交" >
</form>
</template>

<script>
import '../assets/js/gt.js'
export default {
  name: 'slidingBlock1',
  data () {
    return {
    }
  },
  mounted () {
    this.getCaptchaData()
  },
  components: {

  },
  methods: {
    login () {
      let data = this.$qs.stringify(this.form)
      let that = this
      this.$axios.post('api/ajax_validate', data, {withCredentials: true
      })
        .then((res) => {
          console.log(res)
        })
        .catch(function () {
          that.$message.error('账号名或密码错误') // catch里的this不是vue对象,需要外层设置
        })
    },
    getCaptchaData () {
      this.$axios.get('/api/register?t=' + (new Date()).getTime())
        .then((res) => {
          console.log('res', res)
          var handlerEmbed = function (captchaObj) {
            $('#embed-submit').click(function (e) {
              var validate = captchaObj.getValidate()
              if (!validate) {
                $('#notice')[0].className = 'show'
                setTimeout(function () {
                  $('#notice')[0].className = 'hide'
                }, 2000)
                e.preventDefault()
              }
            })
            // 将验证码加到id为captcha的元素里
            captchaObj.appendTo('#embed-captcha')
            captchaObj.onReady(function () {
              $('#wait')[0].className = 'hide'
            })
          // 更多接口参考:http://www.geetest.com/install/sections/idx-client-sdk.html
          }
          // 使用initGeetest接口
          // 参数1:配置参数
          // 参数2:回调,回调的第一个参数验证码对象,之后可以使用它做appendTo之类的事件
          window.initGeetest({
            gt: res.data.gt,
            challenge: res.data.challenge,
            product: 'embed', // 产品形式,包括:float,embed,popup。注意只对PC版验证码有效
            offline: !res.data.success // 表示用户后台检测极验服务器是否宕机,一般不需要关注
          }, handlerEmbed)
        })
        .catch(function (error) {
          console.log(error)
        })
    }
  }
}
</script>

<style>
body {
    margin: 50px 0;
    text-align: center;
}
.inp {
    border: 1px solid gray;
    padding: 0 10px;
    width: 200px;
    height: 30px;
    font-size: 18px;
}
.btn {
    border: 1px solid gray;
    width: 100px;
    height: 30px;
    font-size: 18px;
    cursor: pointer;
}
#embed-captcha {
    width: 300px;
    margin: 0 auto;
}
.show {
    display: block;
}
.hide {
    display: none;
}
#notice {
    color: red;
}
</style>

这里axio获得数据使用代理的方式

打印获取的数据

使用vuex的,可以结合参考文档1使用

(2)form-methods提交按钮提交

为了区别,将验证码卸载id为captcha的容器里

          var handlerEmbed = function (captchaObj) {
            captchaObj.appendTo('#captcha')
            captchaObj.onReady(function () {
              document.getElementById('wait').style.display = 'none'
            })
            captchaObj.onSuccess(function () {
              _this.form.isDisabled = !_this.isDisabled
              _this.form.writeCode = !_this.writeCode
              _this.form.geetest_challenge = captchaObj.getValidate().geetest_challenge
              _this.form.geetest_validate = captchaObj.getValidate().geetest_validate
              _this.form.geetest_seccode = captchaObj.getValidate().geetest_seccode
              console.log(_this.form)
            })
            captchaObj.onError(function () {
              console.log('出错啦,提示用户稍后进行重试')
            })
          }

主要是在回调函数的initGeetest部分重写handlerEmbed,将回调的部分数据加入post数据里

注意:删除提交按钮类型

    login () {
      let data = this.$qs.stringify(this.form)
      console.log(data)
      let that = this
      this.$axios.post('/api/ajax_validate/', data, {withCredentials: true
      })
        .then((res) => {
          console.log(res)
          if (res.data.status === 'fail') {
            $('#notice')[0].className = 'show'
            setTimeout(function () {
              $('#notice')[0].className = 'hide'
            }, 2000)
          }
        })
        .catch(function () {
          that.$message.error('账号名或密码错误') // catch里的this不是vue对象,需要外层设置
        })
    },

添加登录按钮方法,对返回的结果进行判断,通过隐藏/显示来提示用户验证码情况

附件:slidingBlock2.vue

<!-- slidingBlock2:form-methods部分 -->
<template>
<form class="popup"  method="post">
    <p>
      <label for="user">用户名:</label>
      <input class="inp" id="user" type="text" :value="form.username">
    </p>
    <br>
    <p>
      <label for="password">密&nbsp;&nbsp;&nbsp;&nbsp;码:</label>
      <input class="inp" id="password" type="password" :value="form.password">
    </p>
    <div id="embed-captcha"></div>
    <div id="captcha"></div>
    <p id="wait" class="show">正在加载验证码......</p>
    <p id="notice" class="hide">请先拖动验证码到相应位置</p>
    <br>
    <input class="btn" id="embed-submit" value="提交" v-on:click="login()">
</form>
</template>

<script>
import '../assets/js/gt.js'
export default {
  name: 'slidingBlock2',
  data () {
    return {
      form: {
        username: '极验验证',
        password: '123456',
        isDisabled: true,
        writeCode: true
      }
    }
  },
  mounted () {
    this.getCaptchaData()
  },
  components: {

  },
  methods: {
    login () {
      let data = this.$qs.stringify(this.form)
      console.log(data)
      let that = this
      this.$axios.post('/api/ajax_validate/', data, {withCredentials: true
      })
        .then((res) => {
          console.log(res)
          if (res.data.status === 'fail') {
            $('#notice')[0].className = 'show'
            setTimeout(function () {
              $('#notice')[0].className = 'hide'
            }, 2000)
          }
        })
        .catch(function () {
          that.$message.error('账号名或密码错误') // catch里的this不是vue对象,需要外层设置
        })
    },
    getCaptchaData () {
      let _this = this
      this.$axios.get('/api/register?t=' + (new Date()).getTime())
        .then((res) => {
          console.log('res', res)
          var handlerEmbed = function (captchaObj) {
            captchaObj.appendTo('#captcha')
            captchaObj.onReady(function () {
              document.getElementById('wait').style.display = 'none'
            })
            captchaObj.onSuccess(function () {
              _this.form.isDisabled = !_this.isDisabled
              _this.form.writeCode = !_this.writeCode
              _this.form.geetest_challenge = captchaObj.getValidate().geetest_challenge
              _this.form.geetest_validate = captchaObj.getValidate().geetest_validate
              _this.form.geetest_seccode = captchaObj.getValidate().geetest_seccode
              console.log(_this.form)
            })
            captchaObj.onError(function () {
              console.log('出错啦,提示用户稍后进行重试')
            })
          }
          // 使用initGeetest接口
          // 参数1:配置参数
          // 参数2:回调,回调的第一个参数验证码对象,之后可以使用它做appendTo之类的事件
          window.initGeetest({
            gt: res.data.gt,
            challenge: res.data.challenge,
            product: 'embed', // 产品形式,包括:float,embed,popup。注意只对PC版验证码有效
            offline: !res.data.success // 表示用户后台检测极验服务器是否宕机,一般不需要关注
          }, handlerEmbed)
        })
        .catch(function (error) {
          console.log(error)
        })
    }
  }
}
</script>

<style>
body {
    margin: 50px 0;
    text-align: center;
}
.inp {
    border: 1px solid gray;
    padding: 0 10px;
    width: 200px;
    height: 30px;
    font-size: 18px;
}
.btn {
    border: 1px solid gray;
    width: 100px;
    height: 30px;
    font-size: 18px;
    cursor: pointer;
}
#embed-captcha {
    width: 300px;
    margin: 0 auto;
}
.show {
    display: block;
}
.hide {
    display: none;
}
#notice {
    color: red;
}
</style>

可以得到返回成功的信息

后端结合使用框架的注册、登录部分修改代码(略)

三、其他

在查找的过程中,网上有不少使用python和selenium库破解极验证的(B站就是),方法主要是使用库对图片进行灰度处理,识别图片,找到拼图范围,滑动坐标达到。所以这种验证不是非常安全。有时间再看看有没其他更好用的人机验证

参考文档:

1.vue2.0 + 极验验证:https://blog.csdn.net/XiaoYi0215/article/details/79921967?utm_source=blogxgwz0

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏软件测试经验与教训

XSS漏洞总结

同源策略 影响源的因素:host,子域名,端口,协议 a.com通过以下代码:

87630
来自专栏Danny的专栏

ASP.NET 实现发送邮件 + 多个收件人 + 多个附件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/...

47220
来自专栏進无尽的文章

扒虫篇-Debug几个实用的方法

Bebug调试程序是开发中最常见的问题,对于一些简单有效的调试技巧的了解是很有必要的。这篇文章就列举Debug中用到的一些简单的技巧。

27010
来自专栏C语言及其他语言

C语言逆向系列之破解一个简单的C语言程序

以下正文 本节教程将教大家如何去逆向分析和破解一个简单的C程序,需要大家熟悉基本的C语言语法,用到工具有:VC6、IDAPro、OD、UE等工具。 下面我们开...

56050
来自专栏西安-晁州

vuejs、eggjs、mqtt全栈式开发设备管理系统

vuejs、eggjs、mqtt全栈式开发简单设备管理系统 业余时间用eggjs、vuejs开发了一个设备管理系统,通过mqtt协议上传设备数据至web端实时展...

3.2K70
来自专栏西安-晁州

vue.js应用开发笔记

看vue.js有几天了,之前也零零散散的瞅过,不过一直没有动手去写过demo,这几天后台事比较少,一直在讨论各种需求(其实公司对需求还是比较重视与严谨的,一个项...

55710
来自专栏小程序容器

OpenApplus小程序容器

OpenApp+ (https://www.openapplus.com)一个小程序容器,配置简单、功能完善、界面流畅、开箱即用!使用OpenApp+可以快速扩...

67990
来自专栏Albert陈凯

MAC上iTerm 2安装与使用

iTerm2是MAC下最好用的终端工具,并且还是免费的。iTerm2 是配置完毕开箱即用的 tmux,有标签变色、智能选中等特色功能。在日常开发中,我们难免会与...

84220
来自专栏数据科学学习手札

(数据科学学习手札50)基于Python的网络数据采集-selenium篇(上)

  接着几个月之前的(数据科学学习手札31)基于Python的网络数据采集(初级篇),在那篇文章中,我们介绍了关于网络爬虫的基础知识(基本的请求库,基本的解析库...

18840
来自专栏用户2442861的专栏

linux之ldconfig工具的使用

ldconfig是一个动态链接库管理命令 为了让动态链接库为系统所共享,还需运行动态链接库的管理命令--ldconfig ldconfig  命令的用途...

13810

扫码关注云+社区

领取腾讯云代金券