这里我们使用 开源的AJ-Captcha行为验证码,包含滑动拼图、文字点选两种方式。
参考官方文档和开源页面,使用比较简单,但是有几个坑
vue端实现验证码弹出窗
- 提示1:在开源页下载整个项目后,需要把captcha-master.zip\captcha-master\view\vue\src\assets\image复制到你vue项目对应路径下
- 提示2:
@success="'success'"要把单引号去掉,:mode="'pop'"、:captchaType="'blockPuzzle'"要保留单引号
- 提示3:verifition\utils\axios.js中默认的网址前缀是axios.defaults.baseURL = process.env.BASE_API,根据需要修改,例如我修改成
axios.defaults.baseURL = "http://127.0.0.1/api"
也可以用constants.js设置全局变量
springboot实现校验
- 提示1:依赖包要导入 <artifactId>spring-boot-starter-captcha</artifactId>,再配置application.properties,这样启动才能访问到…/captcha/get和…/captcha/check
- 提示2:复制springboot\src\main\resources\images到项目static文件夹下,修改application.properties图片路径
aj.captcha.jigsaw=classpath:static/images/jigsaw
aj.captcha.pic-click=classpath:static/images/pic-click
- 提示3:如果有拦截安全设置,放行…/captcha/get和…/captcha/check
- 提示4:如果前端校验成功,发起登录请求或者发起发送短信验证码请求,在后端就需要第二次校验(防止用户恶意调用接口)
vue示例中使用技巧使axios同时传输@RequestBody请求体和@RequestParam请求参数的数据
success(params){
// params 返回的二次验证参数, 和登录参数一起回传给登录接口,方便后台进行二次验证
//captchaVerification是必传参数
this.captcha = params.captchaVerification
//假设用axios发起post登录请求
this.$http.post("/user/login",
{ //请求体
username:"xing",
password:"1234",
},
{
params:{captcha:this.form.captcha,},//网址携带请求参数
}
)
.then((response)=>{
if(response.data.code === 0){//登录成功
this.$message({
message: '登录成功',
type: 'success',
});
localStorage.setItem("user",JSON.stringify(response.data.data));//保存用户信息
this.$router.push("/");
}
else{
this.$message.error("用户名或密码错误,请重试!!!");
}
})
.catch((error)=>{
//未接受到response的网络传输等错误
console.log(error);
});
},
login登录方法要校验验证码通过,才执行登录逻辑。代码中CommonResult返回结果类、CustomException自定义异常类和Jwt之前文章实现过,Jwt实现登录鉴权文章链接,视频链接。
@PostMapping("/user/login")
public CommonResult<Object> login(@RequestBody User user,@RequestParam String captcha) {
//必传参数:captchaVO.captchaVerification
//验证码的判断逻辑
CaptchaVO captchaVO = new CaptchaVO();
captchaVO.setCaptchaVerification(captcha);
ResponseModel response = captchaService.verification(captchaVO);
if(response.isSuccess() == false){
//验证码校验失败,返回信息告诉前端,或抛出异常
throw new CustomException(Integer.parseInt(response.getRepCode()), response.getRepMsg());
}
//验证码通过,使用登录逻辑
user = userService.findByUsernameAndPassword(user);
if (user == null) {
return CommonResult.failed(001, Message.createMessage("用户名或密码错误!!!"));
} else {
//生成用户对应的Token
String token = JwtTokenUtils.genToken(user.getId().toString(), user.getPassword());
user.setToken(token);
//不传输密码
user.setPassword("");
return CommonResult.success(user);
}
}