【教程】使用VAPTCHA2.0手势验证码加固登录页面 [复制链接]
【作者】Shawna 2020年3月17日 20:13:55

使用VAPTCHA 2.0手势验证码加固登录页面 – 基础

1. 开发前准备

a) 注册VAPTCHA账号 官网:https://www.vaptcha.com/
b) 根据需求,增加验证单元(KEY千万不要泄露,“场景”根据需求自定义)

VAPTCHA

2. 部署代码(本次以点击式为例)

a) 准备登录界面Login.html,在登录表单(id=”login-form” method=”post”)下,在原有的账号input(name=”Account”)和密码input(name=”Password”)后面放置VAPTCHA的加载框和加载动画。

  1. <html>
  2. <head></head>
  3. <body>
  4. <div id="vaptchaContainer" style="width: 220px;height: 40px;margin: 10px;">
  5. <div class="vaptcha-init-main">
  6. <div class="vaptcha-init-loading">
  7. <a href="/" target="_blank"> <img src="https://r.vaptcha.com/public/img/vaptcha-loading.gif" /> </a>
  8. <span class="vaptcha-text">Vaptcha启动中...</span>
  9. </div>
  10. </div>
  11. </div>
  12. </body>
  13. </html>

官方是这么说的:

  1. <!-- 点击式按钮建议高度介于36px与46px -->
  2. <!-- 嵌入式仅需设置宽度,高度根据宽度自适应,最小宽度为200px -->
  3. <div id="vaptchaContainer" style="width: 300px;height: 36px;">
  4. <!--vaptcha-container是用来引入VAPTCHA的容器,下面代码为预加载动画,仅供参考-->
  5. <div class="vaptcha-init-main">
  6. <div class="vaptcha-init-loading">
  7. <a href="/" target="_blank">
  8. <img src="https://r.vaptcha.com/
  9. public/img/vaptcha-loading.gif" />
  10. </a>
  11. <span class="vaptcha-text">Vaptcha启动中...</span>
  12. </div>
  13. </div>
  14. </div>
  15. <script src="https://v.vaptcha.com/v3.js"></script>
  16. <script>
  17. vaptcha({
  18. //配置参数
  19. vid: '****', // 验证单元id
  20. type: 'click', // 展现类型 点击式
  21. container: '#vaptchaContainer', // 按钮容器,可为Element 或者 selector
  22. ... //其他配置参数省略
  23. }).then(function (vaptchaObj) {
  24. vaptchaObj.render()// 调用验证实例 vaptchaObj 的 render 方法加载验证按钮
  25. ... //其他事件处理
  26. })
  27. </script>

所以我们放到页面中以后,就是这样的:

效果

b) 上图中,可能已经注意到了容器下面有两个script标签,现在,我们需要引用vaptcha的js和配置初始化代码。
引用VACTPHA新版v3.js

<script src="https://v.vaptcha.com/v3.js"></script>

参考官方手册:

效果

配置初始化代码:

  1. var obj;
  2. vaptcha({
  3. vid: '5dc3efcb15347d90a5084298',
  4. // 验证单元id
  5. type: 'click',
  6. // 显示类型 点击式
  7. scene: 1,
  8. // 场景值 默认0
  9. container: '#vaptchaContainer',
  10. // 容器,可为Element 或者 selector
  11. offline_server: 'https://www.codecommunity.cn/',
  12. //离线模式服务端地址
  13. lang: 'zh-CN',
  14. https: true,
  15. color: 'rgb(' + normal_bgcolor + ')'
  16. }).then(function(vaptchaObj) {
  17. obj = vaptchaObj; //将VAPTCHA验证实例保存到局部变量中
  18. vaptchaObj.render(); // 调用验证实例 vpObj 的 render 方法加载验证按钮
  19. //获取token的方式一:
  20. vaptchaObj.renderTokenInput('.login-form'); //以form的方式提交数据时,使用此函数向表单添加token值
  21. //关闭验证弹窗时触发
  22. vaptchaObj.listen('close',
  23. function() {
  24. //验证弹窗关闭触发
  25. })
  26. })

官方手册有详细解释:

官方手册

i. 需要注意的一点,在v2版本中验证场景一般要首位补0,比如01、02,但在v3版本中不需要进行补零,例如1、2。
ii. 离线模式服务器地址本次教程不做讲解,但该参数官方不允许为空,直接填写自己的域名地址即可。

c) 配置完成后,写登录按钮的事件,注意的一点,上面代码可以看到我用的是验证单元验证通过后向表单添加token值,实际上,验证单元完成后,表单会增加一个看不到的input(name=” vaptcha_token” value=”验证后的token”),我们不希望用户不输入表单内容就直接提交,验证input是否为空的方法很多,这里用数组进行操作。

  1. function sub() {
  2. //因为下面的数组操作时也会验证这个input,所以我们抢先一步对此进行验证,如果觉得麻烦,可以直接在下面循环处进行验证
  3. if (obj.getToken() == null || obj.getToken() === "") {
  4. $('.Main_Login_Text').html("请先完成验证");
  5. return false;
  6. }
  7. //获取表单所有的可输入组件
  8. let form = $('#login-form').serializeArray();
  9. let flag = -1; //也可以写 =1,后面的else删掉。
  10. $.each(form,
  11. function(i, item) {
  12. if (item['value'] === '') { //循环验证是否为空
  13. $('.Main_Login_Text').html("账号或密码不能为空");
  14. flag = -1;
  15. return false;
  16. } else {
  17. flag = 1;
  18. }
  19. });
  20. if (flag === 1) {
  21. $('#login-form').submit(); //表单没有空,提交给服务器验证
  22. }
  23. }

d) 截止到现在,登录Login.html内容全部完成了。

3. 开始部署服务器二次验证代码(本次demo用的是php7.0版本):

a) 官方文档中提示用post向服务器发送验证token请求,url地址:http://0.vaptcha.com/verify
b) 这里附上php发送post请求的代码(采用file_get_contents方式):

  1. private function send_post($url, $post_data)
  2. {
  3. $postdata = http_build_query($post_data);
  4. $options = array(
  5. 'http' => array(
  6. 'method' => 'POST',
  7. 'header' => 'Content-type:application/x-www-form-urlencoded',
  8. 'content' => $postdata,
  9. 'timeout' => 10 * 60 // 超时时间(单位:s)
  10. )
  11. );
  12. $context = stream_context_create($options);
  13. $result = file_get_contents($url, false, $context);
  14. return $result;
  15. }

c) 在服务端一定要再次验证各项数据,包括是否是空,或者是否包含特殊字符,尤其要注意过滤一下单引号、双引号和”—“符号(可以简单使用addslashes函数进行初步过滤),防止不法分子进行sql注入。

  1. if ($Account != "" && $Password != "" && $Token != "") {
  2. //传参前已对变量进行了过滤验证,这里简单验证一下即可
  3. if ($Token != "") {
  4. $vaptcha_url = "http://0.vaptcha.com/verify";
  5. $post_data = array(
  6. 'id' => '换成自己的验证单元vid',
  7. 'secretkey' => '换成自己的验证单元key',
  8. 'scene' => '1',
  9. 'token' => $Token,
  10. 'ip' => $_SERVER['REMOTE_ADDR'],
  11. );
  12. $result = json_decode($this::send_post($vaptcha_url, $post_data), true);
  13. if ($result['success'] == 1 && $result['score'] >= 1) {
  14. //验证通过,执行的代码
  15. } else {
  16. //验证失败,执行的代码
  17. }
  18. }
  19. }

4. 当你已经进行到了这一步,那么恭喜,你的登录界面已经可以上传测试了。

5. 这里附上官方手册地址和代码demo:

a) 官方手册地址:https://www.vaptcha.com/document/install.html

b) 代码demo:

Login.html
  1. <form action="Login.html" id="login-form" method="post">
  2. <input class="Main_Login_Input" name="Account" placeholder="账号/邮箱/手机号" required=required type="text" value="">
  3. <input class="Main_Login_Input" name="Password" placeholder="登录密码" required=required type="password" value="">
  4. <div id="vaptchaContainer" style="width: 220px;height: 40px;margin: 10px;">
  5. <div class="vaptcha-init-main">
  6. <div class="vaptcha-init-loading">
  7. <a href="/" target="_blank">
  8. <img src="https://r.vaptcha.com/public/img/vaptcha-loading.gif"/>
  9. </a>
  10. <span class="vaptcha-text">Vaptcha启动中...</span>
  11. </div>
  12. </div>
  13. </div>
  14. <script src="https://v.vaptcha.com/v3.js"></script>
  15. <script>
  16. var obj;
  17. vaptcha({
  18. vid: '5dc3efcb15347d90a5084298', // 验证单元id
  19. type: 'click', // 显示类型 点击式
  20. scene: 1, // 场景值 默认0
  21. container: '#vaptchaContainer', // 容器,可为Element 或者 selector
  22. offline_server: 'https://www.codecommunity.cn/', //离线模式服务端地址
  23. lang: 'zh-CN',
  24. https: true,
  25. color: 'rgb(' + normal_bgcolor + ')'
  26. }).then(function (vaptchaObj) {
  27. obj = vaptchaObj;//将VAPTCHA验证实例保存到局部变量中
  28. vaptchaObj.render();// 调用验证实例 vpObj 的 render 方法加载验证按钮
  29. //获取token的方式一:
  30. vaptchaObj.renderTokenInput('.login-form');//以form的方式提交数据时,使用此函数向表单添加token值
  31. //关闭验证弹窗时触发
  32. vaptchaObj.listen('close', function () {
  33. //验证弹窗关闭触发
  34. })
  35. })
  36. </script>
  37. <span class="Main_Login_Input_Span">
  38. <a class="Main_Login_Input_Span_Reg_A" href="#">忘记密码?</a>
  39. </span>
  40. <button class="Main_Login_Input_Button" onclick="sub()" type="button" value="login" name="type">登录</button>
  41. <span class="Main_Login_Input_Span_Reg">
  42. <a class="Main_Login_Input_Span_Reg_A" href="Register.html">注册账号</a>
  43. </span>
  44. </form>
Login.php
  1. if ($Account != "" && $Password != "" && $Token != "") {
  2. if ($Token != "") {
  3. $vaptcha_url = "http://0.vaptcha.com/verify";
  4. $post_data = array(
  5. 'id' => '换成自己的验证单元vid',
  6. 'secretkey' => '换成自己的验证单元key',
  7. 'scene' => '1',
  8. 'token' => $Token,
  9. 'ip' => $_SERVER['REMOTE_ADDR'],
  10. );
  11. $result = json_decode($this::send_post($vaptcha_url, $post_data), true);
  12. if ($result['success'] == 1 && $result['score'] >= 1) {
  13. //验证通过
  14. } else {
  15. //验证失败
  16. }
  17. }
  18. }

6. 最后附上一句:本例程仅为初步使用vaptcha免费版,用于产品时,请根据官方手册配置离线模式,以及购买vaptcha高级版。

7. 感谢!

最终效果

Codecommunity.cn
Shawna
2020年3月16日