【注意】:适用與springboot項目
1.加載jar包。由于groupId的不同,圖檔驗證碼的樣式會有所不同
<!--計算類型的驗證碼 -->
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version>
</dependency>
//-----------分割線---------------------
<!-- 6位數字的驗證碼-->
<dependency>
<groupId>com.github.axet</groupId>
<artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version>
</dependency>
2.配置kaptcha,在配置類中配置
- 計算類型驗證碼的配置類
@Configuration
public class CaptchaConfig
{
@Bean(name = "captchaProducerMath")
public DefaultKaptcha getKaptchaBeanMath()
{
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
Properties properties = new Properties();
// 是否有邊框 預設為true 我們可以自己設定yes,no
properties.setProperty("kaptcha.border", "yes");
// 邊框顔色 預設為Color.BLACK
properties.setProperty("kaptcha.border.color", "105,179,90");
// 驗證碼文本字元顔色 預設為Color.BLACK
properties.setProperty("kaptcha.textproducer.font.color", "blue");
// 驗證碼圖檔寬度 預設為200
properties.setProperty("kaptcha.image.width", "160");
// 驗證碼圖檔高度 預設為50
properties.setProperty("kaptcha.image.height", "60");
// 驗證碼文本字元大小 預設為40
properties.setProperty("kaptcha.textproducer.font.size", "35");
// KAPTCHA_SESSION_KEY
properties.setProperty("kaptcha.session.key", "kaptchaCodeMath");
// 驗證碼文本生成器
properties.setProperty("kaptcha.textproducer.impl", "com.ruoyi.gateway.config.KaptchaTextCreator");
// 驗證碼文本字元間距 預設為2
properties.setProperty("kaptcha.textproducer.char.space", "3");
// 驗證碼文本字元長度 預設為5
properties.setProperty("kaptcha.textproducer.char.length", "6");
// 驗證碼文本字型樣式 預設為new Font("Arial", 1, fontSize), new Font("Courier", 1,
// fontSize)
properties.setProperty("kaptcha.textproducer.font.names", "Arial,Courier");
// 驗證碼噪點顔色 預設為Color.BLACK
properties.setProperty("kaptcha.noise.color", "white");
// 幹擾實作類
properties.setProperty("kaptcha.noise.impl", "com.google.code.kaptcha.impl.NoNoise");
// 圖檔樣式 水紋com.google.code.kaptcha.impl.WaterRipple
// 魚眼com.google.code.kaptcha.impl.FishEyeGimpy
// 陰影com.google.code.kaptcha.impl.ShadowGimpy
properties.setProperty("kaptcha.obscurificator.impl", "com.google.code.kaptcha.impl.ShadowGimpy");
Config config = new Config(properties);
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
}
- 6位數字的驗證碼的配置類
@Configuration
public class KaptchaConfig {
@Bean
public DefaultKaptcha producer() {
Properties properties = new Properties();
properties.put("kaptcha.border", "no");
properties.put("kaptcha.textproducer.font.color", "black");
properties.put("kaptcha.textproducer.char.space", "5");
Config config = new Config(properties);
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
}
3.生成驗證碼并且擷取
- 圖一的
@Slf4j
@Component
@AllArgsConstructor
public class ImgCodeHandler implements HandlerFunction<ServerResponse>
{
private final Producer producer;
private final StringRedisTemplate redisTemplate;
@Override
public Mono<ServerResponse> handle(ServerRequest serverRequest)
{
// 生成驗證碼
String capText = producer.createText();
String capStr = capText.substring(0, capText.lastIndexOf("@"));
String code = capText.substring(capText.lastIndexOf("@") + 1);
BufferedImage image = producer.createImage(capStr);
// 儲存驗證碼資訊
String randomStr = UUID.randomUUID().toString().replaceAll("-", "");
redisTemplate.opsForValue().set(Constants.DEFAULT_CODE_KEY + randomStr, code, 60, TimeUnit.SECONDS);
// 轉換流資訊寫出
FastByteArrayOutputStream os = new FastByteArrayOutputStream();
try
{
ImageIO.write(image, "jpg", os);
}
catch (IOException e)
{
log.error("ImageIO write err", e);
return Mono.error(e);
}
return ServerResponse.status(HttpStatus.OK).contentType(MediaType.IMAGE_JPEG).header("randomstr", randomStr)
.body(BodyInserters.fromResource(new ByteArrayResource(os.toByteArray())));
}
}
- 圖二的
@GetMapping("captcha.jpg")
public void captcha(HttpServletResponse response) throws ServletException, IOException {
response.setHeader("Cache-Control", "no-store, no-cache");
response.setContentType("image/jpeg");
// 生成文字驗證碼
String text = producer.createText();
// 生成圖檔驗證碼
BufferedImage image = producer.createImage(text);
// 儲存到驗證碼到 session
ShiroUtils.setSessionAttribute(Constants.KAPTCHA_SESSION_KEY, text);
ServletOutputStream out = response.getOutputStream();
ImageIO.write(image, "jpg", out);
IOUtils.closeQuietly(out);
}
4.登入接口增加驗證碼驗證
-
圖一的
暫無
- 圖二的
/**
* 登入接口
*/
@PostMapping(value = "/login")
public HttpResult login(@RequestBody LoginBean loginBean) throws IOException {
String userName = loginBean.getAccount();
String password = loginBean.getPassword();
String captcha = loginBean.getCaptcha();
// 從session中擷取之前儲存的驗證碼跟前台傳來的驗證碼進行比對
Object kaptcha = ShiroUtils.getSessionAttribute(Constants.KAPTCHA_SESSION_KEY);
if(kaptcha == null){
return HttpResult.error("驗證碼已失效");
}
if(!captcha.equals(kaptcha)){
return HttpResult.error("驗證碼不正确");
}
// 使用者資訊
SysUser user = sysUserService.findByName(userName);
// 賬号不存在、密碼錯誤
if (user == null) {
return HttpResult.error("賬号不存在");
}
if (!match(user, password)) {
return HttpResult.error("密碼不正确");
}
// 賬号鎖定
if (user.getStatus() == 0) {
return HttpResult.error("賬号已被鎖定,請聯系管理者");
}
// 生成token,并儲存到資料庫
SysUserToken data = sysUserTokenService.createToken(user.getId());
return HttpResult.ok(data);
}