SpringBoot 整合 kaptcha 进行图片验证码人机校验,用token+redis替代session完成验证。
基本原理图实现代码1. 导入kaptcha2. 添加kaptcha配置常用配置配置类配置
先上效果图实现代码
基本原理图
实现代码
1. 导入kaptcha
在porm.xml配置文件添加依赖,并Reimport
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
2. 添加kaptcha配置
常用配置
属性详情默认值
kaptcha.border图片边框,合法值:yes , no"yes"kaptcha.border.color边框颜色,合法值: "255,255,255" 或者 "255,255,255,Alpha" 或者 java.awt.Color 包所有的颜色名称:blue、green、yellow (Alpha的取值范围0-255)"black"kaptcha.border.thickness边框厚度,合法值:>0"1"kaptcha.textproducer.char.string文本集合,验证码值从此集合中获取"abcde2345678gfynmnpwx"kaptcha.textproducer.char.length验证码长度"5"kaptcha.textproducer.font.names文本字体"Arial,Courier"kaptcha.textproducer.font.size字体大小"40"kaptcha.textproducer.char.space字符间隔"2""kaptcha.noise.color"干扰颜色 合法值同 kaptcha.border.color"black""kaptcha.obscurificator.impl"遮光罩: 水纹com.google.code.kaptcha.impl.WaterRipple鱼眼com.google.code.kaptcha.impl.FishEyeGimpy阴影com.google.code.kaptcha.impl.ShadowGimpy"com.google.code.kaptcha.impl.WaterRipple""kaptcha.image.width"图片宽"200""kaptcha.image.height"图片高"50"
配置类配置
@Configuration
public class kaptchaConfig {
@Bean
public DefaultKaptcha getDefaultKaptcha(){
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
Properties properties = new Properties();
properties.setProperty("kaptcha.border.color","34,53,193,155");
properties.setProperty("kaptcha.border.thickness","5");
properties.setProperty("kaptcha.textproducer.char.length","6");
properties.setProperty("kaptcha.textproducer.font.names","宋体,Arial,Courier");
properties.setProperty("kaptcha.noise.color","blue");
Config config = new Config(properties);
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
}
先上效果图
获取token 使用token获取验证码 redis这边
实现代码
获取token
public ResultVO getToken() {
//生成唯一字符串作为token
String token = UUID.randomUUID().toString();
//存入redis
redisTemplate.opsForValue().set(token,new JSONObject().toJSONString());
return ResultVOUtil.succese(token);
}
获取验证码
public void getVerify(String token, HttpServletResponse response) {
//判断token是否存在redis,不存在则重新生成
if(!redisTemplate.hasKey(token)){
throw new LoginException(ResultEnum.TOKEN_NOT_NULL.getCode(),ResultEnum.TOKEN_NOT_NULL.getMsg());
}
//生成验证码字符
String text = producer.createText();
//将验证码字符序列化存入redis
redisTemplate.opsForValue().set(token,JsonUtil.add(redisTemplate.opsForValue().get(token),RedisMapEnum.VERIFY_CODE.getKey(),text));
//使用验证码字符生成验证码图片
BufferedImage image = producer.createImage(text);
//设置头,输出格式与不缓存
response.setContentType("image/jpeg");
response.setHeader("Cache-Control","no-cache");
ServletOutputStream outputStream = response.getOutputStream();
//使用ImageIO向前端输出图片
ImageIO.write(image,"jpeg",outputStream);
}
登录
public ResultVO login(LoginForm loginForm) {
String token = loginForm.getToken();
//验证验证码是否正确
if(!checkVerifyCode(token,loginForm.getVerifyCode())){
return ResultVOUtil.error(ResultEnum.VERIFY_ERROR.getCode(),ResultEnum.VERIFY_ERROR.getMsg());
}
//验证账号密码
ManagerDao managerDao = managerService.findOne(loginForm.getManagerId());
if(managerDao == null || managerDao.getManagerPwd() != loginForm.getManagerpwd()){
return ResultVOUtil.error(ResultEnum.LOGIN_ERROR.getCode(),ResultEnum.LOGIN_ERROR.getMsg());
}
//登录成功,将权限信息存入redis
redisTemplate.opsForValue().set(token,JsonUtil.add(redisTemplate.opsForValue().get(token),RedisMapEnum.MANAGER_WEIGH.getKey(),managerDao.getJurisdictionDao().getManagerWeigh()));
return ResultVOUtil.succese();
}
验证验证码字符的代码
private boolean checkVerifyCode(String token, String verifyCode){
//从redis取出验证码字符进行比对
String code = JsonUtil.get(redisTemplate.opsForValue().get(token),RedisMapEnum.VERIFY_CODE.getKey());
if(code == null || code != verifyCode){
return false;
}
return true;
}
JsonUtil 代码
//这里用到了alibaba.fastjson包
public class JsonUtil {
public static String add(String json,String key, Object value){
JSONObject jsonObject = JSON.parseObject(json);
jsonObject.put(key,value);
return jsonObject.toJSONString();
}
public static String get(String json, String key){
JSONObject jsonObject = JSON.parseObject(json);
return jsonObject.getString(key);
}
}