如何实现图形验证码?入门基础知识_验证码菜鸟知识

细心的同学可以发现,现在很多网站当登录多次之后就会出现一个图形验证码,或是当提交表单、或点击获取手机验证码等等场景都会有图形验证码的出现。那么图形验证码是为了解决什么问题而出现的呢?什么是图形验证码图形验证码是验证码的一种。验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Comput

如何实现图形验证码?入门基础知识

那么图形验证码是为了解决什么问题而出现的呢?

如何实现图形验证码?入门基础知识_验证码菜鸟知识

什么是图形验证码

图形验证码是验证码的一种。验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的公共全自动程序。可以防止:恶意破解密码、刷票、论坛灌水,有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试,实际上用验证码是现在很多网站通行的方式。

既然图形验证码是为了区分机器和人之间的操作,那么我们就可以在图形上绘制一个只有人可以解答的问题。比较常见的是在图片上生成文字验证码,然后用户输入图片上的文字吻合则验证通过。

虽然这种验证方法已经渐渐的被其他更先进的方法所淘汰了(图片上的文字依然可以被程序识别读取),并且前端生成验证码的方式相较于后端安全性不高,但我们的目的只是为了装x,提升程序的安全性只是附带的效果。

登录表单

首先我们需要在在登录表单上额外添加用于输入验证码的FormItem,并且给图形验证码提供一个canvas容器。有时候生成的验证码看不明白,因此需要给验证码添加点击事件用以切换验证码:

<Form ref="loginForm" :model="form" :rules="rules">
    <FormItem prop="userName">
        <Input v-model="form.userName" placeholder="请输入用户名">
            <span slot="prepend">
                <Icon :size="16" type="person"></Icon>
            </span>
        </Input>
    </FormItem>
    <FormItem prop="password">
        <Input type="password" v-model="form.password" placeholder="请输入密码">
            <span slot="prepend">
                <Icon :size="14" type="locked"></Icon>
            </span>
        </Input>
    </FormItem>
    <FormItem prop="valiCode" v-show="this.count">
        <Input v-model="form.valiCode" placeholder="请输入验证码">
            <span slot="prepend">
                <Icon :size="14" type="ios-analytics"></Icon>
            </span>
        </Input>
        <div class="canvas" @click="getImgYanzheng">
            <canvas id="canvas"></canvas>
        </div>
    </FormItem>
    <FormItem>
        <Button @click="handleSubmit" type="primary" long>登录</Button>
    </FormItem>
</Form>

需要用到的属性

表单需要额外添加valiCode用以记录用户输入的验证码。此处我们定义当用户登录失败一次则需要额外输入图形验证码,因此添加count属性,当登陆失败时count++,当然这样的处理方式并不是很严谨,并且用户刷新页面count则会清零。可以在此处可以增加更多限制,如异地登录等,由于本案例完全没有涉及到后端程序,因此只是简单的以count为判断依据。

data() {
    return {
      form: {
        userName: "",// 用户名
        password: "",// 密码
        valiCode: ""// 验证码
      },
      count: 0, // 登录次数
      show_num: [],// 图形上的文字
    }
}

生产图形验证码

页面上为canvas容器绑定的方法getImgYanzheng就是在绘制图形验证码

。在绘制图形验证码时需要为你的验证码定义一个内容集合,此处使用的是:A,B,C,E,F,G,H,J,K,M,N,P,Q,R,S,T,W,X,Y,Z,1,2,3,4,5,6,7,8,9,0,好,医,生。字母中剔除了容易误识别的几个字母并且可以随意加入文字(因此图形验证码也可在做成随机生成四个文字让用户点击,或者生成成语让用户填空等等各种形式)。并且忽略用户大小写,因此需要用到toLowerCase方法。

接下来就是canvas绘图的一些技巧了。

canvas绘图

canvas 元素本身是没有绘图能力的。所有的绘制工作必须在 JavaScript 内部完成:

var c=document.getElementById("myCanvas");
var cxt=c.getContext("2d");

在JavaScript 中使用 id 来寻找 canvas 元素,然后创建context对象,getContext(“2d”) 对象是内建的 HTML5 对象,拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。我们可以把canvas 想象成景色而context则是景色呈现的画布。

由于绘制验证码的过程中是从左往右绘制的,因此需要规划好画布的使用范围,另外在验证码绘制时还要加上一些随机的元素使验证码不容易被程序识别。

getImgYanzheng() {
      var show_num = [];
      var canvas_width = 150; //document.getElementById("canvas").style.width;
      var canvas_height = 30; //document.getElementById("canvas").style.height;
      var canvas = document.getElementById("canvas"); //获取到canvas的对象,景色
      var context = canvas.getContext("2d"); //获取到canvas画图的环境,景色呈现的画布
      canvas.width = canvas_width;
      canvas.height = canvas_height;
      var sCode =
        "A,B,C,E,F,G,H,J,K,M,N,P,Q,R,S,T,W,X,Y,Z,1,2,3,4,5,6,7,8,9,0,好,医,生";
      var aCode = sCode.split(",");
      var aLength = aCode.length; //获取到数组的长度

      for (var i = 0; i <= 3; i++) {
        var j = Math.floor(Math.random() * aLength); //获取到随机的索引值
        var deg = (Math.random() * 30 * Math.PI) / 180; //产生0~30之间的随机弧度
        var txt = aCode[j]; //得到随机的一个内容
        show_num[i] = txt.toLowerCase();
        var x = 10 + i * 20; //文字在canvas上的x坐标
        var y = 20 + Math.random() * 8; //文字在canvas上的y坐标
        context.font = "bold 23px 微软雅黑";

        context.translate(x, y);
        context.rotate(deg);

        context.fillStyle = this.randomColor();
        context.fillText(txt, 0, 0);

        context.rotate(-deg);
        context.translate(-x, -y);
      }
      for (var i = 0; i <= 5; i++) {
        //验证码上显示线条
        context.strokeStyle = this.randomColor();
        context.beginPath();
        context.moveTo(
          Math.random() * canvas_width,
          Math.random() * canvas_height
        );
        context.lineTo(
          Math.random() * canvas_width,
          Math.random() * canvas_height
        );
        context.stroke();
      }
      for (var i = 0; i <= 30; i++) {
        //验证码上显示小点
        context.strokeStyle = this.randomColor();
        context.beginPath();
        var x = Math.random() * canvas_width;
        var y = Math.random() * canvas_height;
        context.moveTo(x, y);
        context.lineTo(x + 1, y + 1);
        context.stroke();
      }
      this.show_num = show_num;
    },

验证码及线条需要一些随机的颜色:

randomColor() {
      //得到随机的颜色值
      var r = Math.floor(Math.random() * 256);
      var g = Math.floor(Math.random() * 256);
      var b = Math.floor(Math.random() * 256);
      return "rgb(" + r + "," + g + "," + b + ")";
    }

有了以上两个方法,图形验证码就已经生成完毕了,接下来就是使用的问题了。

使用图形验证码

判断登录次数count,如果登录次数大于0则需要输入验证码:

const self = this;
if (this.count) {
        if (this.form.valiCode) {
            if (this.show_num.join("") != this.form.valiCode.toLowerCase()) {
                self.$Notice.warning({
                    title: "验证码错误"
                });
                return;
            }
        } else {
            self.$Notice.warning({
                title: "请输入验证码"
            });
            return;
        }
    }

当登录失败时需要执行count++并且刷新验证码:

self.count++;
self.getImgYanzheng();
self.$Notice.warning({
title: "登陆失败",
desc: rs.data.msg
});

此时就完成了一个图形验证码的添加工作,同学们快装起来吧。

如何实现图形验证码?入门基础知识_验证码菜鸟知识

海计划公众号
(0)
上一篇 2020/03/24 05:39
下一篇 2020/03/24 05:39

您可能感兴趣的内容

  • nodejs如何解决高并发?菜鸟教程网_并发菜鸟知识

    nodejs如何解决高并发?菜鸟教程网 Node可以在不新增额外线程的情况下,依然可以对任务进行并发处理 —— Node.js是单线程的。它通过事件循环(event loop)来实…

    2020/03/20
  • js中(function(){…})()立即执行函数写法理解菜鸟教程下载_函数小白攻略

    ( function(){…} )()和( function (){…} () )是两种javascript立即执行函数的常见写法,最初我以为是一个括号包裹匿名函数,再在后面加个括号调用函数,最后达到函数定义后立即执行的目的,后来发现加括号的原因并非如此。要理解立即执行函数,需要先理解一些函数的基本概念。函数声明、函数表达式、匿名函数函数声明:functio

    2020/03/26
  • 把 WebAssembly 用于提升速度和代码重用使用帮助_WebAssembly零基础入门

    有这样一种技术,可以把用高级语言编写的非 Web 程序转换成为 Web 准备的二进制模块,而无需对 Web 程序的源代码进行任何更改即可完成这种转换。浏览器可以有效地下载新翻译的模块并在沙箱中执行。执行的 Web 模块可以与其他 Web 技术无缝地交互 – 特别是 JavaScript(JS)。欢迎来到WebAssembly。对于名称中带有 assembly

    2020/03/26
  • 程序员的工资到底花到哪里去了?使用指南_程序员作者: 黄小斜小白知识

    大家都知道,程序员是一个比较公认的高薪职业。小王就是北京的一个程序员,在中关村上班,现在月薪也有2万出头了,扣掉个税和五险一金,一个月到手也有1万5。当然,每个月在租房成本也高达3000多,扣除房租水电等一些基础生活费用,小王每个月可能也就能剩个8000元。这还是比较省吃俭用的情况下才有的节余,但是小王平时喜欢出去旅游,偶尔也会去跟朋友吃饭。聚会喝酒加上这些

    2020/03/29
  • css常用样式整理菜鸟教程网css属性大全_样式菜鸟教程

    一. 字体属性:(font)1. 大小 {font-size: x-large;}(特大) xx-small;(极小) 一般中文用不到,只要用数值就可以,单位:PX、PD2. 样式 {font-style: oblique;}(偏斜体) italic;(斜体) normal;(正常)3. 行高 {line-height: normal;}(正常) 单位:PX

    2020/04/03
  • CSS动画@keyframes的用法基础知识教程_动画使用说明

    CSS动画CSS动画允许大多数HTML元素的动画,而无需使用JavaScript或Flash!动画浏览器支持IE10+支持该属性的。其他低浏览器版本数字后跟-ms-, -webkit-,-moz-或-o-指定使用前缀的第一个版本。什么是CSS动画?动画允许元素从一种样式逐渐变为另一种样式。您可以根据需要多次更改所需的CSS属性。要使用CSS动画,必须首先为动

    2020/03/29
  • JavaScript是怎样AOP实现?基础知识入门_AOP使用攻略

    AOP的概念,使用过Spring的人应该都不陌生了。Dojo中,也是支持AOP的。对于JavaScript的其他框架、库不知道有没有AOP的支持。而Aop又叫面向切面编程,用过spring的同学肯定对它非常熟悉,而在js中,AOP是一个被严重忽视的技术点,这次就来说说AOP在js中的妙用 .AOP的思维就是在目标方法前后加入代码:var result = n

    2020/04/03
  • 移动端开发必须知道的小技巧菜鸟教程_技巧菜鸟教程网

    最近在公司写一个混合 app 项目,页面基本全部都是用 H5 完成,嵌入到原生 webview 下。发现一个问题,在 iPhone 6 下 苹果手机的状态栏会挡住页面,导致页面下移,样式错乱,最后网上查找了些解决办法,加了一条 meta 标签解决了问题。今天特来总结下常用的移动端开发需要注意的meta标签及一些小技巧。viewport<meta name="

    2020/03/26
  • js中scroll滚动入门知识_滚动菜鸟教程下载

    scroll,滚动,一般讨论的是网页整体与浏览器之间的关系。一.元素相关属性/方法解释element.scrollHeight返回元素的整体高度。element.scrollWidth返回元素的整体宽度。element.scrollLeft返回元素左边缘与视图之间的距离。element.scrollTop返回元素上边缘与视图之间的距离。这四个属性,全部是只读

    2020/03/24
  • WebAssembly菜鸟知识_一种小体积,高加载速度的二进制编码格式

    WebAssembly菜鸟知识 官方网址:http://webassembly.github.io/ GitHub:https://github.com/WebAssembly/d…

    2020/03/06
  • Neataptic使用说明_为浏览器和Node.js提供快速的神经进化和反向传播

    Neataptic使用说明 官方网址:https://wagenaartje.github.io/neataptic/ GitHub:https://github.com/wage…

    2020/03/07
  • Docker—大型项目容器化改造使用攻略_Docker使用帮助

    虚拟化和容器化是项目云化不可避免的两个问题。虚拟化由于是纯平台操作,一个运行于linux操作系统的项目几乎不需要做任何改造就可以支持虚拟化。而项目如果要支持容器化则需要做许多细致的改造工作。容器化相对于虚拟化的优势也相当明显,运行于裸机性能高,秒级启停容器,更不用说开发、测试、布署一致的环境(DevOps理念),以及上篇提到的微服务的能力。大家还可以找到各种

    2020/03/31
  • typescript中类型断言理解小白攻略_断言入门基础教程

    typescript中类型断言好理解也好用类型断言是个好用的玩意,虽然typescript很强大,但是有时还不如我们知道一个值的类型,导致在开发过程中总是报一些令人头痛的类型错误。使用断言,简单来说就是先做好一个假设,使得编译通过。我一开始接触类型断言时是有点不明白的,后来我了解到原因是 “**类型断言更像是类型的选择,而不是类型转换”。**我发现不少博客文

    2020/03/22
  • 让你的网站支持iOS13 Darkmode 模式的工具入门基础_模式基础指南

    最近iOS13 发布了darkmode模式。虽然本人觉得次此功能呼声大于实际,但作为一个以用户体验为己任的前端,当然不能坐视不管,我们总该做点什么。在进行了一番调研了解后,我们有几种支持darkmode模式的方法。首先了解到一个叫 Darkmode.js 的工具,该工具通过配置一些通用的颜色,能让网站实现一键切换darkmode模式,简单方便。但缺点就是没办

    2020/03/23
  • Js对象属性的特性 和defineProperty方法菜鸟指南_特性基础教程

    对象是无序属性的集合,而这些属性在创建是都带有一些特征值(可以理解为属性的属性,天生自带的),这些特征值是为了实现JavaScript引擎用的,因此JavaScript不能直接访问。JavaScript通过这些特征值来定义属性的行为(属性是否删除,枚举,修改等)。例如,在全局定义的属性是会挂载到window上的。当想删除window上的这个属性,是不可以的。

    2020/03/23
  • 利用Hexo来快速搭建博客系统菜鸟教程网_Hexo入门基础知识

    Hexo是什么Hexo 是一个快速、简洁且高效的博客框架。Hexo 使用 Markdown(或其他渲染引擎)解析文章,在几秒内,即可利用靓丽的主题生成静态网页。Hexo安装要使用Hexo,需要在你的系统中支持Nodejs以及Git。 Node.js下载:https://nodejs.org/en/Git下载:http://git-scm.com/downl

    2020/04/05