云e办(后端)——登录验证码
图像验证码显示功能使用 google Kaptcha 验证码产品 实现前台验证码显示功能
一、生成验证码
1、添加依赖
<!-- google kaptcha依赖 -->
<dependency>
<groupId>com.github.axet</groupId>
<artifactId>kaptcha</artifactId>
<version>0.0.9</version>
</dependency>
2、验证码配置类 CaptchaConfig.java
/**
* 验证码配置类
*/
@Configuration
public class CaptchaConfig {
@Bean
public DefaultKaptcha getDefaultKaptcha(){
//验证码生成器
DefaultKaptcha defaultKaptcha=new DefaultKaptcha();
//配置
Properties properties = new Properties();
//是否有边框
properties.setProperty("kaptcha.border", "yes");
//设置边框颜色
properties.setProperty("kaptcha.border.color", "105,179,90");
//边框粗细度,默认为1
// properties.setProperty("kaptcha.border.thickness","1");
//验证码
properties.setProperty("kaptcha.session.key","code");
//验证码文本字符颜色 默认为黑色
properties.setProperty("kaptcha.textproducer.font.color", "blue");
//设置字体样式
properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
//字体大小,默认40
properties.setProperty("kaptcha.textproducer.font.size", "30");
//验证码文本字符内容范围 默认为abced2345678gfynmnpwx
// properties.setProperty("kaptcha.textproducer.char.string", "");
//字符长度,默认为5
properties.setProperty("kaptcha.textproducer.char.length", "4");
//字符间距 默认为2
properties.setProperty("kaptcha.textproducer.char.space", "4");
//验证码图片宽度 默认为200
properties.setProperty("kaptcha.image.width", "100");
//验证码图片高度 默认为40
properties.setProperty("kaptcha.image.height", "40");
Config config = new Config(properties);
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
}
3、提供验证码 生成接口
/**
* 验证码
*/
@RestController
public class CaptchaController {
@Autowired
private DefaultKaptcha defaultKaptch;
@ApiOperation(value = "验证码")
@GetMapping(value = "/captcha",produces="image/jpeg")
public void captcha(HttpServletRequest request, HttpServletResponse response){
//通过流的形式传播图片。
//定义response输出类型为Imag/jpeg类型
response.setDateHeader("Expires", 0);
// Set standard HTTP/1.1 no-cache headers.
response.setHeader("Cache-Control", "no-store, no-cache, mustrevalidate");
// Set IE extended HTTP/1.1 no-cache headers (use addHeader).
response.addHeader("Cache-Control", "post-check=0, pre-check=0");
// Set standard HTTP/1.0 no-cache header.
response.setHeader("Pragma", "no-cache");
// return a jpeg
response.setContentType("image/jpeg");
//-------------------生成验证码 begin --------------------------
//业务逻辑:
//获取验证码的文本内容
String text = defaultKaptch.createText();
System.out.println(text);
//有了验证码,那么肯定要和用户输入的进行比较。
//会把验证码文本内容放到session里面,从session中获取进行比较
request.getSession().setAttribute("captcha",text);
//得到图形验证码
BufferedImage image = defaultKaptch.createImage(text);
ServletOutputStream outputStream = null;
try{
outputStream = response.getOutputStream();
//输出流输出图片
ImageIO.write(image,"jpg",outputStream);
outputStream.flush();
}catch (IOException e){
e.printStackTrace();
}finally{
if(null != outputStream) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//-------------------生成验证码 end --------------------------
}
}
4、放行验证码接口
图形验证码,在登录的时候就需要获取。那么就需要在securityconfig配置里面的进行图形验证码放行。
5、测试
二、校验验证码
此时我们只是生成了验证码,并不能进行验证。
1、登录参数对象添加验证码属性
2、登录方法添加验证码判断
登录返回token的接口:LoginController
3、判断 IAdminService.java
/**
* 登录返回token
*
* @param username
* @param password
* @param code
* @param request
* @return
*/
@Override
public RespBean login(String username, String password, String code,
HttpServletRequest request) {
String captcha = (String) request.getSession().getAttribute("captcha");
if (StringUtils.isBlank(code) || !captcha.equals(code)) {
return RespBean.error("验证码填写错误!");
}
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (null == userDetails || !passwordEncoder.matches(password,
userDetails.getPassword())) {
return RespBean.error("用户名或密码不正确!");
}
if (!userDetails.isEnabled()){
return RespBean.error("账号被禁用,请联系管理员!");
}
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(userDetails, null,
userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
String token = jwtTokenUtil.generateToken(userDetails);
Map<String, String> tokenMap = new HashMap<>();
tokenMap.put("token", token);
tokenMap.put("tokenHead", tokenHead);
return RespBean.success("登录成功", tokenMap);
}
4、测试