文章目录
- 实现流程
- 用户认证
实现流程
1.先引用了google的验证码生成器(Kaptcha)
<dependency><groupId>com.github.axet</groupId><artifactId>kaptcha</artifactId><version>0.0.9</version></dependency>
2.编写Kaptcha的配置类(KaptchaConfig)
/*** 验证码生成配置类*/
@Configuration
public class KaptchaConfig {@Beanpublic DefaultKaptcha producer() {Properties properties = new Properties();properties.put("kaptcha.border", "no");properties.put("kaptcha.textproducer.font.color", "black");properties.put("kaptcha.textproducer.char.space", "4");properties.put("kaptcha.image.height", "40");properties.put("kaptcha.image.width", "120");properties.put("kaptcha.textproducer.font.size", "30");Config config = new Config(properties);DefaultKaptcha defaultKaptcha = new DefaultKaptcha();defaultKaptcha.setConfig(config);return defaultKaptcha;}
}
注: 可以根据自己的喜好,在参数里面对验证码的宽度,高度,大小,颜色等进行修改
3.控制层调用接口信息
@RestController
@Slf4j
public class AuthorController {@Autowiredprivate Producer producer;@Autowiredprivate RedisUtil redisUtil;/*** 验证码* @return*/@GetMapping("/captcha")public Result captcha() throws IOException {String code = producer.createText();String key = UUID.randomUUID().toString();BufferedImage image = producer.createImage(code);ByteArrayOutputStream outputStream = new ByteArrayOutputStream();ImageIO.write(image, "jpg", outputStream);BASE64Encoder encoder = new BASE64Encoder();log.info(code);String str = "data:image/jpeg;base64,";String base64Img = str + encoder.encode(outputStream.toByteArray());// 存储到redis中redisUtil.hset(SysytemContors.CAPTCHA_KEY, key,code,120);log.info("验证码 -- {} - {}", key, code);return Result.succ(MapUtil.builder().put("token", key).put("captchaImg", base64Img).build());}
}
这里我们通过我们之前写的配置类Producer生成一串验证码,同时也通过UUID生成1串随机的Key值,便于我们之后存入到redis中,通过ImageIO的write方法写出一个JPG格式的图片,最后响应给前端,
我们响应的数据
用户认证
当用户认证自己身份时,我们应该先检验用户输入的验证码,接着再检验用户的密码和账户,因此我们需要添加一个验证码的过滤器链
@Component
@Slf4j
public class CaptchaFilter extends OncePerRequestFilter {@Autowiredprivate RedisUtil redisUtil;@Autowiredprivate LoginFailureHandler loginFailureHandler;@Overrideprotected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {//应该先判断该请求是否是Login请求String requestURI = httpServletRequest.getRequestURI();//判断该请求路径是否为登录请求,且请求方式为POST请求if("/login".equals(requestURI) && httpServletRequest.getMethod().equals("POST")){//检查验证码try {checkCaptch(httpServletRequest);}catch (CaptchException captchException){log.info(captchException.getMessage());loginFailureHandler.onAuthenticationFailure(httpServletRequest, httpServletResponse, captchException);}}//成功的话直接放行filterChain.doFilter(httpServletRequest, httpServletResponse);}
我们应先判断用户的请求是否为Login请求,请求方式是否为POST请求,再去验证输入的验证码是否正确,
/*** 校验验证码的流程*/private void checkCaptch(HttpServletRequest httpServletRequest){//先获取用户的CodeString code = httpServletRequest.getParameter("code");String key = httpServletRequest.getParameter("key");//用户没有填验证码if(!StringUtils.hasText(code) || !StringUtils.hasText(key)){throw new CaptchException("验证码异常");}if(!code.equals(redisUtil.hget(SysytemContors.CAPTCHA_KEY, key))){throw new CaptchException("验证码异常");}//从redis中删除redisUtil.hdel(SysytemContors.CAPTCHA_KEY, key);}
注:当我们在验证完验证码后,我们就把该验证码从redis中删除。
最后我们需要将该过滤器链加入SpringSecurity的配置类中