1、生成验证码
整合Captcha生成图形验证码
@Resource(name = "选择缓存方式")
CaptchaCache captchaCache;
@Autowired
Producer kaptchaProducer;
@Override
public Map<String, String> getCaptcha(String key) throws Exception {
// 生成验证码
String code = kaptchaProducer.createText();//随机生成四个验证码
BufferedImage kaptchaImage = kaptchaProducer.createImage(code);//根据验证码生成图片
// 生成BASE64
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(kaptchaImage, "jpg", outputStream);
String base64Img = Base64.getEncoder().encodeToString(outputStream.toByteArray());
//返回给用户的验证码图片
Map<String, String> imgMap = new HashMap<>();
imgMap.put(key, "data:image/jpeg;base64," + base64Img);
Map<String, String> cacheMap = new HashMap<>();
cacheMap.put(CODE, code.toUpperCase());
//服务端存储校验信息
captchaCache.putCaptcha(key, cacheMap);
return imgMap;
}
2、验证码校验
SpringBoot 通过实现HandlerInterceptor接口实现拦截器,通过实现WebMvcConfigurer接口实现一个配置类,在配置类中注入拦截器,最后再通过 @Configuration 注解注入配置
@Configuration
public class SpringMvcConfiguration implements WebMvcConfigurer {
@Bean
public CaptchaHandlerInterceptor captchaHandlerInterceptor() {
return new CaptchaHandlerInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry){
WebMvcConfigurer.super.addInterceptors(registry);
registry.addInterceptor(captchaHandlerInterceptor());
}
}
实现HandlerInterceptor接口
实现HandlerInterceptor接口需要实现 1个方法:preHandle。preHandle负责在调用login登录接口前判断验证码是否正确。
public class CaptchaHandlerInterceptor implements HandlerInterceptor {
private final Logger log = LoggerFactory.getLogger(CaptchaHandlerInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
if (handler instanceof HandlerMethod) {
BiyiCaptcha biyiCaptcha = ((HandlerMethod) handler).getMethodAnnotation(BiyiCaptcha.class);
// controller没有添加BiyiCaptcha注解
if (biyiCaptcha == null) {
return true;
}
//获取BiyiCaptcha注解中的属性
String ruleName = biyiCaptcha.rule();
log.debug(ruleName);
String serviceName = biyiCaptcha.service();
log.debug(serviceName);
//根据注解中的bean名获取spring容器中的bean
ValidateRule rule = (ValidateRule) SpringUtil.getBean(ruleName);
CaptchaService service = (CaptchaService) SpringUtil.getBean(serviceName);
log.debug(request.getHeader(CaptchaConstant.CAPTCHA_KEY));
log.debug(request.getHeader(CaptchaConstant.CAPTCHA));
//如果请求header中带有key和captcha
if (StringUtil.isNotEmpty(request.getHeader(CaptchaConstant.CAPTCHA_KEY))
&& StringUtil.isNotEmpty(request.getHeader(CaptchaConstant.CAPTCHA))) {
String key = request.getHeader(CaptchaConstant.CAPTCHA_KEY);
log.debug(key);
String captchaJson = request.getHeader(CaptchaConstant.CAPTCHA);
log.debug(captchaJson);
@SuppressWarnings("unchecked")
Map<String,String> captcha = (Map<String,String>)JacksonUtil.json2Bean(captchaJson, Map.class);
log.debug(captcha.toString());
//比较验证码
if(rule.accordWihtRule(key)) {
if(service.validateCaptcha(key,captcha)) {
log.debug("Captcha validate success");
return true;
}else {//验证码认证失败
throw new CaptchaValidateException(request.getRequestURI());
}
}
} else {//请求header中没有
throw new BadRequestAlertException(ErrorConstants.CAPTCHA_TYPE, "The information of captcha is missing", "captcha.header", "missing");
}
}
return true;
}
}
3、生成token
通过JWT工具类生成token
//通过各种操作判断这个判断那个然后生成token
String jwt = this.tokenProvider.createToken(authentication, rememberMe);
将token返给客户端