图形验证码是验证码的一种。验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试的缩写,是一种区分用户是计算机仍是人的公共全自动程序。能够防止:恶意破解密码、刷票、论坛灌水,有效防止某个***对某一个特定注册用户用特定程序暴力破解方式进行不断的登录尝试,实际上用验证码是如今不少网站通行的方式。前端
既然图形验证码是为了区分机器和人之间的操做,那么咱们就能够在图形上绘制一个只有人能够解答的问题。比较常见的是在图片上生成文字验证码,而后用户输入图片上的文字吻合则验证经过。ios
虽然这种验证方法已经渐渐的被其余更先进的方法所淘汰了(图片上的文字依然能够被程序识别读取),而且前端生成验证码的方式相较于后端安全性不高,但咱们的目的只是为了装x,提高程序的安全性只是附带的效果。web
首先咱们须要在在登陆表单上额外添加用于输入验证码的FormItem,而且给图形验证码提供一个canvas容器。有时候生成的验证码看不明白,所以须要给验证码添加点击事件用以切换验证码:canvas
web前端开发学习Q-q-u-n: ⑦⑧④-⑦⑧③-零①②,分享学习的方法和须要注意的小细节,不停更新最新的教程和学习方法(详细的前端项目实战教学视频) <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绘图的一些技巧了。dom
canvas 元素自己是没有绘图能力的。全部的绘制工做必须在 JavaScript 内部完成:ide
var c=document.getElementById("myCanvas"); var cxt=c.getContext("2d");
在JavaScript 中使用 id 来寻找 canvas 元素,而后建立context对象,getContext("2d") 对象是内建的 HTML5 对象,拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。咱们能够把canvas 想象成景色而context则是景色呈现的画布。学习
因为绘制验证码的过程当中是从左往右绘制的,所以须要规划好画布的使用范围,另外在验证码绘制时还要加上一些随机的元素使验证码不容易被程序识别。
web前端开发学习Q-q-u-n: 731771211,分享学习的方法和须要注意的小细节,不停更新最新的教程和学习方法(详细的前端项目实战教学视频) 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 });
此时就完成了一个图形验证码的添加工做,同窗们快装起来吧。