在网上看到一个很方便的验证码插件:easy-captcha 。使用效果如下。
使用步骤:
1.导入依赖
<!--图形验证码-->
<dependency>
<groupId>com.github.whvcse</groupId>
<artifactId>easy-captcha</artifactId>
<version>1.6.2</version>
</dependency>
2.后端生成验证码并输出给前端(前端加载时请求此接口)
@ApiOperation(value = "获取验证码")
@RequestMapping("v1/captcha")
public void captcha(javax.servlet.http.HttpServletRequest request, HttpServletResponse response) throws Exception {
// 设置请求头为输出图片类型
response.setContentType("image/gif");
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
//字母类型
//SpecCaptcha captcha = new SpecCaptcha(130, 48, 4);
// 中文gif类型
//ChineseGifCaptcha captcha = new ChineseGifCaptcha(130, 48);
// 中文类型
//ChineseCaptcha captcha = new ChineseCaptcha(130, 48);
// 算术类型
ArithmeticCaptcha captcha = new ArithmeticCaptcha(130, 48); // 图片的宽高
captcha.setLen(2); // 几位数运算,默认是两位
captcha.getArithmeticString(); // 获取运算的公式:3+2=?
captcha.text(); // 获取运算的结果:5
//验证码存入session或存入redis
//存redis通过UUID.randomUUID()生成key,specCaptcha.text().toLowerCase()生成value,存入redis并将key返回给前端,在登录时从redis中获取并验证
//存session则如下,
request.getSession().setAttribute("captcha", captcha.text().toLowerCase());
// 输出图片流
captcha.out(response.getOutputStream());
}
我默认使用的算术类型的验证码。另外由于接口 有jwt的token校验,但是验证码的接口是不需要token校验的,所以我把生成验证码的接口的拦截去掉,
在springboot的配置文件中加入:
jwtp.exclude-path=/v1/captcha
3.前端接收验证码
<div class="layui-inline">
<div class="layui-input-inline">
<input name="verCode" class="layui-input" lay-verify="required" placeholder="验证码" type="text">
</div>
<div class="layui-input-inline">
<img src="/v1/captcha" id="verCodeImg" width="120px" height="48px"/>
</div>
</div>
点击验证码图片,刷新验证码的js
//刷新验证码
$('#verCodeImg').click(function flushVerCode() {
this.src = this.src + "?" + Math.random();
});
点击登录后,关于验证码相关的代码,
function doLogin(field) {
layer.load(2);
admin.req('login', field, function (res) {
layer.closeAll('loading');
if(res.message=="验证码错误"){
/*-------关键代码------start*/
layer.msg(res.message, {icon: 5});
/*刷新验证码*/
var verCodeImg = $('#verCodeImg');
var src = verCodeImg.prop('src');
verCodeImg.prop('src', src + "?" + Math.random());
return false;
/*-------关键代码------end*/
}else{
/*登录成功则做其他操作*/
}
}, 'POST');
}
4.后端验证码校验
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wf.captcha.utils.CaptchaUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* 请求过滤类
**/
@Component
public class ValidateCodeFilter extends OncePerRequestFilter {
@Autowired
private ObjectMapper objectMapper;
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
/*如果请求的url是登录的接口,则进行验证码校验*/
if (StringUtils.pathEquals("/v1/login", httpServletRequest.getRequestURI())) {
String verCode = httpServletRequest.getParameter("verCode");
if (!CaptchaUtil.ver(verCode, httpServletRequest)) {
Map<String, Object> map = new HashMap<>();
map.put("message", "验证码错误");
httpServletResponse.setContentType("application/json;charset=UTF-8");
httpServletResponse.getWriter().write(objectMapper.writeValueAsString(map));
return;
}
}
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
}
到此为止,这个验证码的使用就结束了,比较方便。