整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

springCloud vue实现图片文字点击验证验证码



Spring Cloud和Vue中实现图片文字点击验证验证码的功能,你需要考虑以下几个步骤:

  1. 后端生成验证码图片:你可以使用Spring Cloud的Hystrix服务实现这一功能,其中Spring Cloud提供了生成图片验证码的功能。
  2. 前段展示图片并验证:在Vue中,你可以使用HTML5的canvas标签来展示图片,并监听点击事件。当用户点击图片上的文字时,你可以通过Ajax请求后端验证用户输入的验证码是否正确。

以下是一个简单的示例:

后端(Spring Cloud)

首先,你需要在Spring Cloud中创建一个服务来生成验证码图片。你可以使用Spring Cloud OpenFeign来调用这个服务。

1. 创建验证码服务

@Service  
public class CaptchaService {  
    @Autowired  
    private CaptchaGenerator captchaGenerator;  
  
    public String generateCaptcha() {  
        String captcha = captchaGenerator.generateCaptcha();  
        // 存储 captcha 到缓存或数据库,以便后续验证  
        return captcha;  
    }  
}

2. 创建接口来返回验证码图片

@RestController  
@RequestMapping("/api/captcha")  
public class CaptchaController {  
    @Autowired  
    private CaptchaService captchaService;  
  
    @GetMapping("/image")  
    public ResponseEntity<byte[]> getCaptchaImage() {  
        String captcha = captchaService.generateCaptcha();  
        // 生成图片并返回  
        // ...  
    }  
}

前端(Vue)

在Vue中,你可以使用HTML5的canvas标签来展示图片,并监听点击事件。当用户点击图片上的文字时,你可以通过Ajax请求后端验证用户输入的验证码是否正确。

1. 安装必要的依赖项(如果尚未安装)

  • axios:用于发送HTTP请求。你可以使用npm或yarn安装它:npm install axios 或 yarn add axios。
  • html2canvas:用于将DOM元素转换为canvas。你可以使用npm或yarn安装它:npm install html2canvas 或 yarn add html2canvas。

2. 在Vue组件中实现功能

在你的Vue组件中,你可以添加一个方法来生成和验证验证码。这里是一个简单的示例:

心的同学可以发现,现在很多网站当登录多次之后就会出现一个图形验证码,或是当提交表单、或点击获取手机验证码等等场景都会有图形验证码的出现。

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

什么是图形验证码

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

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

虽然这种验证方法已经渐渐的被其他更先进的方法所淘汰了(图片上的文字依然可以被程序识别读取),并且前端生成验证码的方式相较于后端安全性不高,但我们的目的只是为了装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
});

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

转评赞就是最大的鼓励

登录网站时往往会需要输入一些乱七八糟甚至难以辨别的验证码以便证明用户是个真实的个人。更糟糕的是,电脑前的你即便试了多次也难以成功。这一问题在今后将不再出现。由创业团队火柴棍工作室研发的“火柴手写码”能抵御插件工具的破解难度,并且同时保证验证码图片的清晰。

火柴手写码,是由一群80/90后码农,在饱受验证码开发之苦后研发出来的。其前端操作过程同一般的验证码输入方式无异。最大不同在于后台技术——它将海量手写图片资源进行碎片化处理,随机组合、加密生成图片验证码,能使现有OCR技术很难识别,更加安全可靠。这对主要通过服务器自动识别验证码的木马软件来说,会起到遏制作用。那么手写验证码的原理是什么?它又有哪些独特之处呢?针对这些问题,CSDN采访了火柴手写码的项目负责人葛付荣。

CSDN:请介绍一下你和你的团队。

葛付荣:我们的团队是由一群开发经验丰富的80/90后码农组成。此前我们主要从事游戏平台和办公平台的开发工作,曾推出过手机助手、积分平台等相关产品,对厂商和用户都有接触与了解。

CSDN:开发手写验证码是出于什么样的契机?

葛付荣:验证码是开发者与使用者都会被困扰的一个问题,并且目前还没有一种最好的解决办法出现。为了寻找用户体验与系统安全间的平衡点,我们曾经不断推出各种验证码,直至2014年11月一次偶然的机会,我们掌握了海量手写字符的生产方法之后,决定将手写字符与验证码技术结合起来并尝试推出火柴手写码。火柴手写码是一种清晰、安全、方便的云验证码服务。

CSDN:火柴手写码与一般验证码有什么不同?

葛付荣:火柴手写码旨在基于海量手写字符与复杂安全技术,为开发者构建云验证码开放平台。其前端操作过程同一般的验证码输入方式无异。最大的不同在于后台技术——火柴手写码是将海量手写图片资源进行碎片化处理,随机组合、加密生成图片验证码,能使现有OCR技术很难识别,更加安全可靠。这对主要通过服务器自动识别验证码的木马软件来说会起到遏制作用。

火柴手写码最大特点是它所采用的手写字符。手写字符的识别工作在OCR领域一直是个难题,目前尚没有高效、低成本的解决方案。因为即便同一个人,在不同时间、不同场景下书写同一个字符,由于书写时的方式、笔、纸张、环境等因素的不同,都可能导致书写结果的不一致。当然,光有原始素材是远远不够的。火柴手写码还需经过过滤、切割、降噪、再组合等过程,才最终形成用户所看到的验证码。而在这一复杂过程中,我们最终得到的是肉眼更易识别,但OCR(Optical Character Recognition,光学字符识别)难以识别的字符验证码。

CSDN:请谈谈火柴验证码的技术实现原理。

葛付荣:传统图片验证码一般是由程序自动扭曲字符生成,因为源图片内容单一、混淆算法有限、干扰因素较多,容易被穷举破解,而且用户体验较差。这就是为什么像12306这类网站即便在前端不断提高用户验证难度,却仍然会被抢票软件轻松破解的原因之一。

然而火柴手写码所采用的手写字符,其识别工作在OCR领域一直是个难题。正如上面所说,即便是同一个人,在不同时间、不同场景下书写同一个字符,由于书写时的方式、笔、纸张、环境等因素的不同,都可能导致书写结果的不一致。下图是同一人书写的24个数字“8”。正是基于人手写字符的难破译性,火柴手写码在经过对国人书写习惯的识别和研究后,形成了稳定手写数据收集渠道,庞大而复杂的字符数据库为火柴手写码的诞生提供素材保障。

CSDN:数据收集之后的具体处理经过是怎样的?

葛付荣:收集到大量手写数据后,火柴手写码还需经过过滤、切割、降噪、再组合等过程,才最终形成用户所看到的验证码。

过滤切割:为增加破解难度,手写素材要经过源数据过滤系统的过滤,以及在有效区域内切割成单字符图片,去除掉模糊、残缺的素材后才可进一步使用。

降噪:经过过滤切割后,还将采用均值滤波器、中值滤波器等图像降噪方法,最大化地去除干扰因素,获得更清晰、肉眼容易识别但OCR难以识别的图片。

再组合:在得到有效的单字符图片后,火柴验证码还需按照一定的算法随机组成,才可形成最终验证码。并且在这一过程中,系统会自动规避掉重复数字以及简单规律数字的组合可能。以6位数字验证码为例,系统会取6张有效的单数字图片组合在一起,如果遇到安全性略差的连续相同数字的话,则会重新组合。

这一系列处理的好处是,保证了手写验证码难以破解,但用户在使用上又不会难以识别。火柴手写码一直坚持简单操作的用户体验原则,所以用作生成手写码的字符都是一些普通用户常见的字符,且字符间距较大,不会出现传统验证码的扭曲、粘连现象,用户更容易辨识,操作更加轻松简单。目前,火柴手写码提供Demo、SDK。开发者可以将手写码轻松地部署到网站或其他产品上。从而节省开发成本。

CSDN:这个项目目前有哪些渠道与其他开发者合作?

葛付荣:火柴手写码一定是与其他开发者合作才有其存在价值与生存空间的。在产品设计之初我们就遵循可轻松部署、快速集成的原则。目前我们已经推出开放平台,希望越来越多的开发者能使用我们的验证码,而不是费时费力地自行开发。

CSDN:2015年在项目运营中有哪些规划?

葛付荣:我们将继续在清晰度与安全性之间寻找平衡点,争取用户一眼就能看清、OCR五秒都无法识别。此外,还计划从目前的纯数字逐渐形成数字、英文字母、简体中文汉字,以及其他特殊字符等多种手写码混排的格局。并且还将尝试每个手写码有且只用一次,以此提供破解复杂度。结合大数据行为分析,火柴手写码还将在不降低安全性的前提下为不同的用户推荐不同的手写码。例如:为喜欢数字的用户提供数字验证码,为喜欢汉字的用户提供汉字验证码等。另一方面,我们在今年计划逐渐将产品推向市场。逐步扩大邀请开发者试用范围,促成更多网站、游戏使用火柴手写码。

【《近匠》AR学校:从教育领域看增强现实机遇何在】《近匠》第77期:从创业公司LeapMotion、uSens到微软,越来越多的公司开始走进VR与AR领域,就连苹果也不例外。“AR学校”从2005年便开始接触AR技术,CEO赵良华从研发与市场角度分析了AR的现状。

【《近匠》SENSORO CTO赵东炜:解密iBeacon生态】《近匠》第76期:微信推出的“摇一摇周边”功能,通过连接人与场景,让iBeacon技术以巧妙的角度融入了我们的生活。技术上,复杂的场景要如何部署?市场上,有哪些机会和问题?为此我们采访了SENSORO的CTO赵东炜。

【《近匠》Amaze UI:做最懂中国程序员的开源HTML5框架】《近匠》75期,HTML5的定稿以及Web组件化让移动Web开发到了异常火爆的地步,跨屏跨平台的开源HTML5开发框架Amaze UI强调移动优先,为国内的开发者提供最具本土特色的组件工具,降低开发门槛,让应用开发变得更简单。

及线下开发者活动信息,请关注mobilehub公众微信号(ID: mobilehub)

寻求《近匠》免费报道,请私信:@CSDN移动,或发送邮件至mobile#csdn.net。