vue 生成图片,怎么用js生成验证码图片
这篇文章主要为大家详细介绍了某视频剪辑软件实现图片验证码生成,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
图片验证码主要用于注册,登录等提交场景中,目的是防止脚本进行批量注册、登录、灌水,相比不带图片验证的安全度有所提高,不过目前也有自动识别图片验证码的程序出现,基本都是付费识别,随之又出现了滑动验证,选取正确选项验证等更加安全的验证方式。但图片验证码码仍用于大部分网站中。
一、前端图片验证码生成
前端逻辑大体就是进行图形绘制,取几个随机数放入图片中,加入干扰,进行验证
1.创建验证码组件identify.vue
模板
div class= s-canvas style= display:inline
画布id= s-canvas :width=内容宽度:height=内容高度/canvas
/div
/模板
脚本
导出默认值{
名称:侧面识别,
道具:{
身份代码:{ //默认注册码
类型:字符串,
默认值:"1234"
},
fontSizeMin: { //字体最小值
类型:数量,
默认值:25
},
fontSizeMax: { //字体最大值
类型:数量,
默认值:35
},
backgroundColorMin: { //验证码图片背景色最小值
类型:数量,
默认值:200
},
backgroundColorMax: { //验证码图片背景色最大值
类型:数量,
默认值:220
},
dotColorMin: { //背景干扰点最小值
类型:数量,
默认值:60
},
dotColorMax: { //背景干扰点最大值
类型:数量,
默认值:120
},
内容宽度:{ //容器宽度
类型:数量,
默认值:117
},
内容高度:{ //容器高度
类型:数量,
默认值:32
}
},
方法:{
//生成一个随机数
随机编号(最小值,最大值){
回归数学。地板(数学。random()*(max-min)min)
},
//生成一个随机的颜色
随机颜色(最小值,最大值){
设r=this.randomNum(最小值,最大值)
设g=this.randomNum(最小值,最大值)
设b=this.randomNum(最小值,最大值)
返回" rgb( r , g , b )"
},
drawPic () {
让画布=文档。getelementbyid( s-canvas )
let ctx=canvas.getContext(2d )
ctx.textBaseline=bottom
//绘制背景
ctx.fillStyle=#e6ecfd
ctx.fillRect(0,0,this.contentWidth,this.contentHeight)
//绘制文字
对于(设I=0;我这个。识别代码。长度;i ) {
this.drawText(ctx,this.identifyCode[i],I)
}
本。画线(ctx)
这个。绘图点(ctx)
},
drawText (ctx,txt,i) {
CTX。填充样式=this。颜色随机(50,160) //随机生成字体颜色
CTX。font=this。random num(这个。font size min,this.fontSizeMax) px SimHei //随机生成字体大小
设x=(I ^ 1)*(这个。内容宽度/(这个。识别代码。长度^ 1))
设y=这个。random num(这个。最大字体大小,this.contentHeight - 5)
var deg=this.randomNum(-30,30)
//修改坐标原点和旋转角度
ctx.translate(x,y)
ctx.rotate(度数*数学/180).
ctx.fillText(txt,0,0)
//恢复坐标原点和旋转角度
CTX . rotate(-deg * Math ./180).
ctx.translate(-x,-y)
},
绘制线(ctx) {
//绘制干扰线
对于(设I=0;I 4;i ) {
CTX。笔画风格=这个。随机颜色(100,200)
ctx.beginPath()
ctx.moveTo(this.randomNum(0,this.contentWidth),this.randomNum(0,this.contentHeight))
ctx.lineTo(this.randomNum(0,this.contentWidth),this.randomNum(0,this.contentHeight))
ctx.stroke()
}
},
绘图点(ctx) {
//绘制干扰点
对于(设I=0;i 30i ) {
CTX。填充样式=this。随机颜色(0.255)
ctx.beginPath()
ctx.arc(this.randomNum(0,this.contentWidth),this.randomNum(0,this.contentHeight),1,0,2 * Math .PI)
ctx.fill()
}
}
},
观察:{
identifyCode () {
this.drawPic()
}
},
已安装(){
this.drawPic()
}
}
/脚本
2.父组件
前端生成验证码的校验是自己生成验证码,用户输入的值和生成的验证码字符串进行比对校验的,校验没有走后端,在真正发送请求到后端的时候也是不将验证码传给后台的。
模板
div slot= content class= reg-body
div class=主要内容
El-form ref= form :model= form :rules= rules label-width= 125 px label-position= left
El-表单-项目标签=验证码我的项目属性=代码
埃尔输入
v-model.trim=form.code
占位符=请输入正确的验证码
大小=小
style=width: 200px
/
log in-code style= position:absolute;右:0;top:4px;左:257像素
识别:识别代码=识别代码/识别
/span
跨度
El-icon-刷新-右
style= position:absolute;左:394 pxtop:13px;光标:指针
@click=refreshCode
/
/El-表单-项目
/el格式
div style=text-align: center
埃尔按钮
v-if=form.agreement
style= background:# 6bc 6a 1;颜色:白色;边框-半径:2px宽度:200像素高度:30px行高:5px边框:无;下边距:10px
@click=submitForm()
:loading=loading
提交/el-button
/div
/div
/div
/模板
脚本
从导入标识符./识别;
导出默认值{
名称:注册,
mixins:[地区],
组件:{标识},
data() {
返回{
表单设置:{
内容宽度:340,
},
表单:{
logoUrl:" ",
licenseUrl: ,
描述:[],
帐户: ,
名称: ,
},
代码:这个. route.query.code,
识别码:“1234567890 abcdefjhijklinopqrsduvwxyz”,
识别码:"",
图片列表:[],
道具:{ label:名称,值: id ,子级:子级 },
规则:{
代码:[{要求:真,消息: 请输入验证码,触发器: change }],
},
表单列表:[],
};
},
已创建(){
//this.getAllDict()
},
已安装(){
这个。获取区域();
//初始化验证码
这个。识别代码=" ";
这个。做代码(这个。识别代码,4);
localStorage.setItem(code ,this。码);
},
方法:{
openHtml() {
this.visible=true
},
//刷新验证码
refreshCode() {
这个。识别代码=" ";
这个。做代码(这个。识别代码,4);
},
//生成验证上的随机数,验证码中的数从识别码中取,
makeCode(o,l) {
对于(设I=0;I l;i ) {
这个。识别码=这个。识别代码[
this.randomNum(0,this.identifyCodes.length)
];
}
},
//生成随机数,这里是生成
//Math.random()方法返回大于等于0小于一的一个随机数
//随机数=Math.floor(Math.random() *可能的总数第一个可能的值)
随机编号(最小值,最大值){
回归数学。地板(数学。random()*(max-min)min);
},
//提交表单
submitForm() {
这个refs[form].验证((有效)={
如果(有效){
如果(this.loading) {
返回;
}
this.loading=true
这个。submit();
}否则{
返回错误的
}
});
},
提交:异步函数(){
if (this.form.code.toLowerCase()!==这个。识别代码。tolowercase()){
这个. msg({ type:错误,消息:请填写正确验证码 });
这个。刷新代码();
this.loading=false
返回;
}否则{
//验证码校验成功就可以调接口提交表单了
},
},
};
/脚本
二、后端生成图片验证码
后台思路很,利用图片类创建一张图片,再用制图法对图片进行绘制(生成随机字符,添加噪点,干扰线)即可。
包com。恒天软件。gxrc。基地。util
导入com。恒天软件。gxrc。常见。不变。magicnumconstant
导入龙目岛。外部人员。SLF 4j。SLF 4j;
导入org。spring框架。刻板印象。组件;
导入javax。imageio。imageio
导入Java。awt。字体;
导入Java。awt。颜色;
导入Java。awt。图形;
导入Java。awt。形象。缓冲图像;
导入Java。io。bytearrayoutputstream
导入Java。util。base64
导入Java。util。hashmap
导入Java。util。地图;
导入Java。util。随机;
@Slf4j
@组件
公共类ImgCaptchaUtil {
私有Random Random=new Random();
/**
* 验证码的宽
*/
private final int width=160
/**
* 验证码的高
*/
private final int height=40
/**
* 验证码的干扰线数量
*/
private final int lineSize=30
/**
* 验证码词典
*/
私有最终字符串random string= 0123456789 abcdefghijklmnopqrstuvwxyz ;
/**
* 获取字体
* @返回
*/
私有字体getFont() {
返回新字体(‘泰晤士新罗马’,字体ROMAN_BASELINE,MagicNumConstant .四十);
}
/**
* 获取颜色
* @param fc
* @param bc
* @返回
*/
private Color getRandomColor(int fc,int bc) {
int fcc=Math.min(fc,MagicNumConstant .两百五十五);
int bcc=Math.min(bc,MagicNumConstant .两百五十五);
int r=FCC随机。nextint(bcc-FCC-MagicNumConstant .十六);
int g=FCC随机。nextint(bcc-FCC-MagicNumConstant .十四);
int b=FCC随机。nextint(bcc-FCC-MagicNumConstant .十二);
返回新颜色(r,g,b);
}
/**
* 绘制干扰线
* @param g
*/
私有空绘制线(图形g) {
int x=random。nextint(宽度);
int y=random。nextint(高度);
int XL=random。nextint(MagicNumConstant .二十);
int yl=random。nextint(MagicNumConstant .十);
g.drawLine(x,y,x xl,y yl);
}
/**
* 获取随机字符
* @参数编号
* @返回
*/
私有字符串getRandomString(int num) {
int number=num 0?num:randomstring。长度();
返回字符串。(随机字符串的值。charat(随机。nextint(number)));
}
/**
* 绘制字符串
* @param g
* @param randomStr
* @param i
* @返回
*/
私有字符串drawString(Graphics g,String randomStr,int i) {
g。设置字体(get font());
g。set color(getRandomColor(MagicNumConstant .一百零八,魔法常数。一百九);
string rand=getRandomString(random。nextint(randomstring。length()));
string random string=randomStr rand;
g。翻译(随机。nextint(MagicNumConstant .三)、随机。nextint(MagicNumConstant .六));
g.drawString(rand,MagicNumConstant .四十* i MagicNumConstant .十、MagicNumConstant .二十五);
返回随机字符串
}
/**
* 生成随机图片,返回base64字符串
* @param
* @返回
*/
公共映射字符串,字符串getImgCodeBaseCode(int length) {
MapString,String result=new HashMap();
//BufferedImage类是具有缓冲区的图像类,图像类是用于描述图像信息的类
BufferedImage=新的buffered image(宽度,高度,BufferedImage .TYPE _ INT _ BGR);
图形g=图像。获取图形();
g.fillRect(0,0,width,height);
//获取颜色
g。set color(getRandomColor(MagicNumConstant .105,MagicNumConstant .一百八十九);
//获取字体
g。设置字体(get font());
//绘制干扰线
for(int I=0;我划线;i ) {
拉线(克);
}
//绘制随机字符
字符串随机码=" ";
for(int I=0;我长度;i ) {
randomCode=drawString(g,randomCode,I);
}
g。dispose();
result.put(imgCode ,随机码);
string base64 code=
尝试{
//返回base64
ByteArrayOutputStream Bos=new ByteArrayOutputStream();
ImageIO.write(image, PNG ,Bos);
byte[]bytes=Bos。tobytearray();
Base64 .编码器编码器=基数64。获取编码器();
base64代码=编码器。编码字符串(字节);
} catch(异常e) {
日志。debug(e . getmessage());
}
result.put(data , data:image/png;base64, base64代码);
返回结果;
}
}
后台生成图片base64,和一个唯一的钥匙(通过这个键判断是哪张图片),后台可以通过接口传给前端图片base64和钥匙,前端输入验证码,传给后台键和验证码去校验验证。
包com。恒天软件。gxrc。基地。服务。impl
导入com。恒天软件。gxrc。基地。服务。imgcaptchaservice
导入com。恒天软件。gxrc。基地。util。imgcaptchautil
导入com。恒天软件。gxrc。常见。不变。magicnumconstant
导入com。恒天软件。gxrc。常见。实体。例外。业务异常;
导入com。恒天柔软。gxrc。常见。雷迪斯。redis distion
导入com。恒天软件。gxrc。常见。util。uuidutils
导入org。阿帕奇。公地。郎3。对象实用程序;
导入org。阿帕奇。公地。郎3。字符串实用程序;
导入org。spring框架。豆子。工厂。注释。自动连线;
导入org。spring框架。数据。雷迪斯。核心。redis模板;
导入org。spring框架。刻板印象。服务;
导入Java。util。地图;
/**
* @描述:
* @作者:吴
* @CreateDate: 2020/11/11 17:17
*/
@服务
公共类ImgCaptchaServiceImpl实现ImgCaptchaService {
私有静态最终字符串IMG _验证码= img验证码:;
@自动连线
private RedisTemplateString,Object redisTemplate .
@自动连线
私人ImgCaptchaUtil
@覆盖
公共映射字符串,字符串getimcaptcha(){
redis distion redis distion=new redis distion(redis模板);
MapString,String map=imgcaptchautil。getimgcodebasecode(MagicNumConstant .四);
string uuid=uuidutils。创建uuid();
redis操作。设置(IMG _验证码uuid,地图。get( img code );
redis操作。过期(IMG _验证码uuid,MagicNumConstant .三万);
地图。删除( img代码);
map.put(key ,uuid);
返回地图;
}
@覆盖
public void checkImgCaptcha(字符串代码,字符串密钥){
redis distion redis distion=new redis distion(redis模板);
字符串CAPTCHA=redis操作。获取(IMG _验证码密钥);
if(object utils。isempty(验证码) !StringUtils.equals(captcha,code)) {
抛出新的BusinessException(验证码错误);
}
redis操作。德尔(IMG)验证码密钥);
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。