使用kaptcha生成验证码的作用:进行人机校验–防止机器脚本,自动大量注册用户。
1.Kaptcha是谷歌开源的可高度配置的实用验证码生成工具。
2.通过Kaptcha可阻拦大多数机器人脚本操作。
3.kaptcha典型殷勇于注册、登录、重要信息提交等用户交互
1.引入kaptcha依赖
2.创建kaptcha配置类
3.创建Controller类,生成验证码
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
@Configuration
public class KaptchaConfig {
/**
* Kaptcha图形验证码工具配置类
*/
@Bean
public Producer kaptchaProducer() {
// 实例一个DefaultKaptcha
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
// 创建配置对象
Properties properties = new Properties();
// 设置边框
properties.setProperty(Constants.KAPTCHA_BORDER, "yes");
// 设置颜色
properties.setProperty(Constants.KAPTCHA_BORDER_COLOR, "105,179,90");
// 设置字体颜色
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black");
// 设置宽度
properties.setProperty(Constants.KAPTCHA_IMAGE_WIDTH, "125");
// 高度
properties.setProperty(Constants.KAPTCHA_IMAGE_HEIGHT, "50");
// 设置session.key
properties.setProperty(Constants.KAPTCHA_SESSION_CONFIG_KEY, "code");
// 设置文本长度
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");
// 设置字体
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
// 设置图片样式
properties.setProperty(Constants.KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
// 将以上属性设置为实例一个DefaultKaptcha的属性
Config config = new Config(properties);
defaultKaptcha.setConfig(config);
// 将defaultKaptcha返回
return defaultKaptcha;
}
}
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import static com.qyzb.base.result.ResultCode.FAILURE;
import static com.qyzb.base.result.ResultCode.SUCCESS;
@Data
@ApiModel("返回结果")
public class R<T> {
/**
* 错误码
*/
@ApiModelProperty("错误码")
private Integer code;
/**
* 错误消息
*/
@ApiModelProperty("错误消息")
private String msg;
/**
* 内容
*/
@ApiModelProperty("内容")
private T data;
public static <U> R<U> toResult(int rows) {
return rows > 0 ? R.success() : R.failure();
}
public static <U> R<U> success() {
return of(SUCCESS, null, null);
}
public static <U> R<U> success(U data) {
return of(SUCCESS, null, data);
}
public static <U> R<U> failure() {
return of(FAILURE, null, null);
}
public static <U> R<U> failure(ResultCode resultCode) {
return of(resultCode, null, null);
}
public static <U> R<U> failure(ResultCode resultCode, String detail) {
return of(resultCode, detail, null);
}
public static <U, E extends CodeException> R<U> exception(E ex) {
return failure(ex.getCode(), ex.getDetail());
}
public static <U> R<U> of(ResultCode resultCode, String detail, U data) {
R<U> result = new R<>();
result.code = resultCode.code();
if (StringUtils.isEmpty(detail)) {
result.msg = resultCode.message();
} else {
//覆盖消息
result.msg = detail;
}
result.data = data;
return result;
}
}
import com.google.code.kaptcha.Producer;
import com.qyzb.base.result.R;
import com.qyzb.base.result.ResultCode;
import com.qyzb.jwt.annotation.PassToken;
import com.qyzb.redis.RedisCache;
import com.qyzb.util.UUIDUtil;
import com.sun.jersey.core.util.Base64;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@RestController
@RequestMapping("/kaptcha")
@Api(value = "验证码" , tags = "验证码")
public class KaptchaController {
@Autowired
private Producer kaptchaProduer;
@Resource
private RedisCache redisCache;
@GetMapping("/image-code")
@ApiOperation("生成图片验证码")
public R<?> getKaptcha(HttpServletResponse response, HttpSession session){
String imagecode = kaptchaProduer.createText();
// 生成图片
BufferedImage image = kaptchaProduer.createImage(imagecode);
// 将验证码存入Session
session.setAttribute("kaptcha",imagecode);
//将图片输出给浏览器
String uuid = UUIDUtil.getUUID();//uuid-->验证码唯一标识
FastByteArrayOutputStream os = new FastByteArrayOutputStream();
try {
response.setContentType("image/png");
ImageIO.write(image,"png",os);
//验证码实现redis缓存,过期时间2分钟
session.setAttribute("uuid",imagecode);
redisCache.add(uuid,imagecode,2, TimeUnit.MINUTES);
} catch (IOException e) {
return R.failure(ResultCode.of(e.getMessage()));
}
Map<String , Object> data = new HashMap<>();
data.put("uuid" , uuid);
data.put("img" , Base64.encode(os.toByteArray()));
return R.success(data);
}
}
import org.apache.commons.lang3.ObjectUtils;
public enum ResultCode {
SUCCESS(200,"成功"),
FAILURE(500,"失败"),
ERROR(10000,"未知原因出错"),
SERVICE_ERROR(50000,"服务器异常");
ResultCode(Integer code, String message) {
this.code = code;
this.message = message;
}
private Integer code;
private String message;
public Integer code() {
return this.code;
}
public String message() {
return this.message;
}
public static ResultCode of(String message) {
if (ObjectUtils.isEmpty(message)) {
throw new RuntimeException("参数错误");
}
for (ResultCode resultCode : values()) {
if (resultCode.message.equals(message)) {
return resultCode;
}
}
return ERROR;
}
}