java生成图片验证码,前端回显
【代码】java生成图片验证码,前端回显。
·
java生成图片验证码
使用场景:
- 获取手机、邮件验证码之前做一层检测是否是人为验证
- 登录、注册之前做一层检测是否是人工验证
- 频繁点击登录、注册接口做一层检测是否是人为验证
一、引入相关依赖
<!-- 添加图形验证码依赖 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-captcha</artifactId>
<version>5.8.6</version>
</dependency>
- createCode 创建验证码,实现类需同时生成随机验证码字符串和验证码图片
- getCode 获取验证码的文字内容
- verify 验证验证码是否正确,建议忽略大小写
- write 将验证码写出到目标流中
- 而AbstractCaptcha为一个ICaptcha抽象实现类,此类实现了验证码文本生成、非大小写敏感的验证、写出到流和文件等方法,通过继承此抽象类只需实现createImage方法定义图形生成规则即可。
二、生成图形验证码(模拟场景发送手机验证码)
/**
* 获取图形验证码
* @param response 请求
* @param captchaCode 前端随机的编码用于验证图形验证码唯一标识
* @return 返回验证码图片64位
*/
@GetMapping("/createCaptcha")
public ApiResult createCaptcha(HttpServletResponse response, @NotNull @RequestParam("captchaCode") String captchaCode) {
String phoneCode = CODE_PHONE_CAPTCHA + captchaCode;
// 定义图形验证码的长和宽
LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);
logger.info("lineCaptcha.getCode(){}",lineCaptcha.getCode());
// 获取的验证码值,缓存起来用于验证
String code = lineCaptcha.getCode();
// 获取图片64位字符串
String imageBase64 = lineCaptcha.getImageBase64();
Map<String, Object> data = Maps.newConcurrentMap();
// 转成图片64位让前端显示
data.put("imageBase64" , imageBase64);
// 前端传参验证码唯一标识
data.put("captchaCode", captchaCode);
// 设置有效期30秒
redisUtils.set(phoneCode , code, 30);
return ApiResult.success("获取成功", data);
}
/**
* 发送短信每个ip限制一天200个请求
*
* @param phone 手机号
* @param captchaValue 验证码值
* @param captchaCode 验证码编码
*/
@ApiOperation(value = "发送短信", notes = "根据手机号发送通用短信")
@ApiImplicitParam(name = "phone", value = "手机号码", required = true, dataType = "String", paramType = "query", example = "15243686469")
@PostMapping("/verificationCodeToPhone")
public ApiResult sendPhoneMsg(HttpServletRequest request,@NotNull @RequestParam("phone") String phone, @NotNull @RequestParam("captchaValue") String captchaValue,
@NotNull @RequestParam("captchaCode") String captchaCode) {
String ipAddress = IpAdrressUtil.getIpAddress(request);
if (redisUtils.hasKey(CODE_IPADDRESS + ipAddress)) {
Integer ipAddressCount = Integer.valueOf(redisUtils.get(CODE_IPADDRESS + ipAddress).toString());
if (ipAddressCount > 200) {
return ApiResult.error("当前IP已被限制发送短信,请求过多,请第二天重试!", 500);
}
redisUtils.incr(CODE_IPADDRESS + ipAddress, 1);
} else {
// 禁止24小时
redisUtils.set(CODE_IPADDRESS + ipAddress, 1, 60 * 60 * 24);
}
// 验证手机格式
if (isMobile(phone)) {
if (!redisUtils.hasKey(CODE_PHONE_CAPTCHA + captchaCode)) {
throw new RuntimeException("图形码验证失败,请先刷新图片验证码重新输入!");
}
String codePhone = redisUtils.get(CODE_PHONE_CAPTCHA + captchaCode).toString();
if (!StringUtils.equals(codePhone,captchaValue)) {
throw new RuntimeException("图形码验证失败,请先刷新图片验证码重新输入!");
}
if (redisUtils.hasKey(CODE_PHONE + phone)) {
throw new RuntimeException("获取验证码失败,请求频繁,稍后再试!!!");
}
String code = roundNum();
SmsUtils.getInstance().sendSms(phone, code);
redisUtils.set(CODE_PHONE + phone, code, 60);
return success(BaseErrorEnum.SUCCESS_SEND_OK.getErrorMessage(), phone);
}
return error(BaseErrorEnum.ERR_PHONE_FORMAT.getErrorMessage());
}
/**
* 验证是否为一个手机号
*
* @param mobiles
* @return
*/
private boolean isMobile(String mobiles) {
String telRegex = "[1][3456789]\\d{9}";
// "[1]"代表第1位为数字1,"[3578]"代表第二位可以为3-9中的一个,"\\d{9}"代表后面是可以是0~9的数字,有9位。
if (TextUtils.isEmpty(mobiles)) {
return false;
} else {
return mobiles.matches(telRegex);
}
}
三、前端转为图片验证码
- JS代码,调用接口
/**
* 获取图形验证码
*/
createCaptchaCode(){
var captchaCode = this.uuid();
var params = {
captchaCode: captchaCode
}
this.captchaCode = captchaCode;
getCreateCaptcha(params, data => {
if (data && data.success){
var datas = data.attributes;
this.imgCodeObj.codeImg = datas.imageBase64;
this.imgCodeObj.codeId = datas.captchaCode;
console.log("data",data)
}
});
console.log("this.captchaCode",this.captchaCode)
},
uuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
return v.toString(16);
});
},
- vue代码(最主要这段::src=“‘data:image/png;base64,’ + imgCodeObj.codeImg”)
<div class="input-group mar-btm" v-show="isPhone">
<input :focus="inputFocus.codeFocus" v-model="captchaValue" id="captchaValue"
@keyup.enter="submit" autocomplete="off" class="form-control "
placeholder="图形验证码" style=" width: 250px; height: 50px;"/>
<span class="input-group-btn" >
<img
@click="createCaptchaCode"
style="margin-top: -30px; width: 140px; height: 50px;"
:src="'data:image/png;base64,' + imgCodeObj.codeImg"
/>
</span>
</div>
四、结果展示
更多推荐
已为社区贡献1条内容
所有评论(0)