前言
验证码在项目中使用到的较多,主要的目的是防止bl破解和自动化脚本攻击。验证码需要人工识别图片中的内容,可以组织批量的自动化攻击。同时可以减轻数据库的访问压力,验证码不通过的情况下,不去进行查表操作。这篇文章大致说明一下具体的实现过程~
实现效果演示
这里的图片二维码是后端接口返回的base64(图片转base64),然后渲染到页面部分。用户点击这个图片可以生成新的验证码。验证码的有效时长是1分钟、超过有效期 ,验证失效。(有效时长可以通过改变验证码存入redis的时长来调整)。

实现过程大致说明
1、后端pom文件引入redis依赖,redis 连接 等下相关配置;
2、生成验证码保存到redis中(同时设置过期时间);
3、将生成的图片验证码以base64格式返回给前端,渲染出来;
4、用户输入的验证码和redis的比对;
后端接口实现(核心部分)
验证码生成部分
/**
* 后台生成图形验证码 :有效
* @param response
* @param key
*/
@getmapping(value = "/randomimage/{key}")
public result randomimage(httpservletresponse response, @pathvariable("key") string key){
logger.info("进入后台生成图形验证码方法 ...");
jsonobject jsonobject = new jsonobject();
try {
//生成验证码
string code = randomutil.randomstring(base_check_codes,4);
//存到redis中
string lowercasecode = code.tolowercase();
// 加入密钥作为混淆,避免简单的拼接,被外部利用,用户自定义该密钥即可
logger.info("rediskey: {}", key);
string keyprefix = md5util.md5encode(key + signature_secret, "utf-8");
string realkey = keyprefix + lowercasecode;
redisutil.removeall(keyprefix);
redisutil.set(realkey, lowercasecode, 60);
logger.info("获取验证码,redis key = {},checkcode = {}", realkey, code);
//返回前端
string base64 = randimageutil.generate(code);
jsonobject.put("base64", base64);
return result.ok().data(jsonobject);
} catch (exception e) {
logger.error(e.getmessage(), e);
return result.error().code(resultcode.get_verify_code_error.getcode())
.message(resultcode.get_verify_code_error.getmessage());
}
}生成base64图片字符串
/**
* 生成base64字符串
* @param resultcode
* @return
* @throws ioexception
*/
public static string generate(string resultcode) throws ioexception {
bufferedimage image = getimagebuffer(resultcode);
bytearrayoutputstream bytestream = new bytearrayoutputstream();
//写入流中
imageio.write(image, img_format, bytestream);
//转换成字节
byte[] bytes = bytestream.tobytearray();
//转换成base64串
string base64 = base64.getencoder().encodetostring(bytes).trim();
//删除 \r\n
base64 = base64.replaceall("\n", "").replaceall("\r", "");
//写到指定位置
//imageio.write(bufferedimage, "png", new file(""));
return base64_pre+base64;
}验证部分,将用户输入的验证码和redis存储的比对。
@requestmapping(value = "/login/userlogin", method = requestmethod.post)
public result loginsystem(@requestbody sysloginmodel sysloginmodel, httpservletrequest request) {
log.info("用户登录开始:{}", sysloginmodel);
string captcha = sysloginmodel.getcaptcha();
string checkkey = sysloginmodel.getcheckkey();
if(captcha==null){
return result.error().code(resultcode.verify_code_error.getcode())
.message(resultcode.verify_code_error.getmessage());
}
string lowercasecaptcha = captcha.tolowercase();
string realkey = md5util.md5encode(checkkey + signature_secret, "utf-8") + lowercasecaptcha;
object checkcode = redisutil.get(realkey);
log.info("redis存储验证码: {} , 用户输入验证码: {}", checkcode , lowercasecaptcha);
if(checkcode == null || !checkcode.equals(lowercasecaptcha)) {
return result.error().code(resultcode.verify_code_not_exist.getcode()).message(resultcode.verify_code_not_exist.getmessage());
}
}前端接口实现 (核心部分)
页面实现部分、用的vue2
<el-form-item prop="captcha"> <div class="captcha-box"> <el-input v-model="form.captcha" placeholder="验证码" prefix-icon="el-icon-key" /> <div class="captcha-img"> <img v-if="randcodedata.requestcodesuccess" style="margin-top: 2px; max-width: initial" :src="randcodedata.randcodeimage" @click="handlechangecheckcode" /> </div> </div> </el-form-item>
js部分实现
handlechangecheckcode() {
const _this = this;
this.randcodedata.checkkey =
new date().gettime() + math.random().tostring(36).slice(-4);
this.$axios
.getrandomimage(_this.randcodedata.checkkey)
.then(function (resp) {
if (resp.code == 200) {
_this.randcodedata.randcodeimage = resp.data.base64;
_this.randcodedata.requestcodesuccess = true;
} else {
_this.$message.error(resp.message);
}
});
},

总结
到此这篇关于使用springboot + vue + redis实现验证码登录功能的文章就介绍到这了,更多相关springboot+vue+redis实现验证码登录内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论