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

细心的同学可以发现,现在很多网站当登录多次之后就会出现一个图形验证码,或是当提交表单、或点击获取手机验证码等等场景都会有图形验证码的出现。那么图形验证码是为了解决什么问题而出现的呢?什么是图形验证码图形验证码是验证码的一种。验证码(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

您可能感兴趣的内容

  • 小程序框架菜鸟教程网推荐多款高质量的小程序框架组件_小程序小白入门

    小程序到底有多火,看看目前推出的开源框架以及组件库就知道了。由于小程序开发的火爆,大家都在致力于探索如何更好的,更加高效的开发小程序,以至于很多公司都贡献了小程序开源框架和组件库。 1、 mpvuempvue 是美团点评开源的一个使用 Vue.js 开发小程序的前端框架。框架基于 Vue.js 核心,mpvue 修改了 Vue.js 的 runtime

    2020/04/03
  • 为什么需要在 JavaScript 中使用严格模式?基础入门_严格模式菜鸟教程下载

    严格模式是什么意思?有什么用途?为什么我们应该使用它? 本文 将主要从这几个问题入手,讲述在 JavaScript 中使用严格模式的必要性。严格模式是现代 JavaScript 的重要组成部分。通过这种模式,我们可以选择使用更为严格的 JavaScript 语法。严格模式的语义不同于以前的 JavaScript“稀松模式”(sloppy mode),后者的语

    2020/03/23
  • js变量提升的坑入门攻略_变量菜鸟攻略

    变量提升在js函数内部是可以直接修改全局的变量的,个人感觉是不好的设计, 但是确实存在这个概念原理:先查看有没有函数变量bb查看形参有没有bb查看全局有没有bb报错, 找不到bb变量修改函数内部var bb = 1;function foo(cc){var bb = 2; // 这里的bb, 其实是函数的局部变量console.log(cc);
    }foo(b

    2020/03/23
  • 前端js实现Blob、DataURL、canvas、image的相互转换新手入门_blob基础知识教程

    canvas转dataURL:canvas对象、转换格式、图像品质function canvasToDataURL(canvas, format, quality){return canvas.toDataURL(format||’image/jpeg’, quality||1.0);
    }DataURL转canvasfunction dataURLToCan

    2020/03/30
  • 深入理解JavaScript之 new 原理及模拟实现菜鸟教程网_new入门百科

    1.定义new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例先看看 new 实现了哪些功能, 先来看一段代码:function Person(age) {this.age = age;
    }
    Person.prototype.getAge = function() {console.log(“年龄为:” + this.age );
    }v

    2020/03/20
  • 独立摇滚明星的成功之道入门基础教程_互联网小白常识

    一提起摇滚明星,就不由得想到酷炫的舞台、疯狂的粉丝和纸醉金迷的生活。可是,如果只靠运气,而缺少奋发图强的特质,也无法走向成功。成为独立的摇滚明星,单靠幸运是不够的多数著名摇滚乐队主唱的成名之路并不是一帆风顺的。多数人都曾经历过社会底层的生活。比如曾在英国大红大紫的摇滚乐队主唱Kasabian在读完大学后,很长时间在农场帮工。还有“涅槃”(Nirvana)乐队

    2020/04/03
  • 从微前端聊聊架构演进 指南攻略_微前端菜鸟指南

    就目前来看,微前端已经不是一个新话题了。随着越来越多的公司的深入研究,当前也提出了很多的解决方案。不过本文不是想要来介绍微前端,更想介绍项目如何一步步到达微前端架构的实际需求。当然,也不排除有些项目在初期就需要微前端这样的架构,不过我一直相信,任何架构模式都是根据实际需求来构建的。为什么很多大公司投入那么多的精力去做这样一件事,更多的也是因为他们真正需要这样

    2020/03/20
  • Mojito基础指南_一个JavaScript的Web应用框架

    Mojito基础指南 官方网址:http://developer.yahoo.com/cocktails/mojito GitHub:https://github.com/Yaho…

    2020/03/06
  • vue-multiselect基础教程_Vue.js 打造的下拉组件

    vue-multiselect基础教程 官方网址:https://vue-multiselect.js.org GitHub:https://github.com/shentao/…

    2020/03/06
  • 程序员必须知道的10大基础实用算法及其讲解菜鸟教程下载_算法使用指南

    算法一:快速排序算法快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。快速排序使用分治法(Divide a

    2020/04/06
  • 资深web前端工程师总结出一套正确的学习思路指南教程_学习零基础入门

    对于零基础的学员来说:初接触一门技术,想要去了解他,并掌握它,是不是觉得有点无从下手,不知道该学习什么?该先学哪个后学哪个?今天一位资深web前端工程师,用他多年从事web前端工作的个人经验总结出一套正确的学习思路,分享给你们!具体来说,前端方面的知识从重要程度来排,应该先后学这些:第一步学习基础知识api学习,系统地学,可以看看这个方面的书,不要只零散地看

    2020/03/22
  • JS 中有趣的事实使用帮助_技巧小白知识

    使用 JS 有很多有趣的地方。尽管工程师们每天都在与之打交道,但仍有一些语言没有被开发出来。本广将介绍一些你可能想不到的JS特性。NaN 是一个 number 类型NaN是一个 number 类型。 而且,NaN 不等于它自己。 实际上NaN不等于任何东西,验证一个变量是否是 NaN 可以使用 isNaN() 方法来判断。> typeof(NaN)
    “num

    2020/03/26
  • NodeJs中的异步使用帮助_异步小白攻略

    这篇文章主要讨论NodeJs中的异步问题。使用NodeJs编写进程也一年多了,在公司实习的时候,公司两个项目的后台都是我负责使用NodeJs和Sails框架编写的。工作模式主要是我在服务器端提供RESTful接口,网页端通过AJAX方式获取服务端的数据。在做的过程中,遇到了许多问题,感触最深的是异步编程的思维习惯还不是适应的很好。异步背景其实,异步很早都有了

    2020/03/26
  • 在react中实现打印功能菜鸟教程网_打印基础教程

    我们知道,window.print()可以调起打印功能,但是直接用window.print()如果直接打印的话,没有样式,而且默认打印的是整个网页的内容。解决的方法可以用iframe方式引入需要打印的区域,并把样式添加进去,然后把iframe标签定位到看不到的地方去。搜了一下,已经有人造好了轮子,react-to-print插件就是这么做的。一.使用方法下载

    2020/03/23
  • Pure.css小白指南雅虎出品的一组轻量级、响应式纯css模块

    Pure.css基础入门 官方网址:https://purecss.io/ GitHub:https://github.com/yahoo/pure/ 简介描述:雅虎出品的一组轻量…

    2020/03/05
  • 5个有趣且不必要的 JavaScipt 技巧基础知识入门_技巧基础知识入门

    前一段时间,我创建了一个标题为“7个可爱的Web开发技巧”的帖子。在这里,我描述了一些有趣的技巧,您可以使用3种主要的Web技术之一来实现这些技巧-HTML,CSS和JavaScript。而且,我必须承认-你们似乎都喜欢它!因此,续集来了!这次,为了更加一致,我决定只专注于JavaScript。它可能是三者中最有趣,用途最广泛的,因此有很多事情要讨论。我们将

    2020/03/23