使用Redis操作验证码
import org.springframework.data.redis.core.StringRedisTemplate;
public class VerifyCodeManager {
private final StringRedisTemplate stringRedisTemplate;
public String genImgVerifyCode(String sessionId) throws IOException {
String verifyCode = ImgVerifyCodeUtils.getRandomVerifyCode(4);
String img = ImgVerifyCodeUtils.genVerifyCodeImg(verifyCode);
stringRedisTemplate.opsForValue().set(CacheConsts.IMG_VERIFY_CODE_CACHE_KEY + sessionId,
verifyCode, Duration.ofMinutes(5));
return img;
}
public boolean imgVerifyCodeOk(String sessionId, String verifyCode) {
return Objects.equals(stringRedisTemplate.opsForValue()
.get(CacheConsts.IMG_VERIFY_CODE_CACHE_KEY + sessionId), verifyCode);
}
public void removeImgVerifyCode(String sessionId) {
stringRedisTemplate.delete(CacheConsts.IMG_VERIFY_CODE_CACHE_KEY + sessionId);
}
}
生成验证码图片
public class ImgVerifyCodeUtils {
private final String randNumber = "0123456789";
private final int width = 100;
private final int height = 38;
private final Random random = new Random();
private Font getFont() {
return new Font("Fixed", Font.PLAIN, 23);
}
public String genVerifyCodeImg(String verifyCode) throws IOException {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
Graphics g = image.getGraphics();
g.fillRect(0, 0, width, height);
g.setColor(new Color(204, 204, 204));
int lineSize = 40;
for (int i = 0; i <= lineSize; i++) {
drawLine(g);
}
drawString(g, verifyCode);
g.dispose();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
ImageIO.write(image, "JPEG", stream);
return Base64.getEncoder().encodeToString(stream.toByteArray());
}
private void drawString(Graphics g, String verifyCode) {
for (int i = 1; i <= verifyCode.length(); i++) {
g.setFont(getFont());
g.setColor(new Color(random.nextInt(101), random.nextInt(111), random
.nextInt(121)));
g.translate(random.nextInt(3), random.nextInt(3));
g.drawString(String.valueOf(verifyCode.charAt(i - 1)), 13 * i, 23);
}
}
private void drawLine(Graphics g) {
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(13);
int yl = random.nextInt(15);
g.drawLine(x, y, x + xl, y + yl);
}
public static String getRandomVerifyCode(int num) {
int randNumberSize = randNumber.length();
StringBuilder verifyCode = new StringBuilder();
for (int i = 0; i < num; i++) {
String rand = String.valueOf(randNumber.charAt(random.nextInt(randNumberSize)));
verifyCode.append(rand);
}
return verifyCode.toString();
}
}
操作Redis的缓存变量
public class CacheConsts {
public static final String IMG_VERIFY_CODE_CACHE_KEY =
REDIS_CACHE_PREFIX + "imgVerifyCodeCache::";
}
DTO
@Data
@Builder
public class ImgVerifyCodeRespDto {
private String sessionId;
private String img;
}
Controller
public class ResourceController {
@Resource
private final ResourceService resourceService;
@PostMapping("imgVerifyCode")
public RestResp<ImgVerifyCodeRespDTO> getImgVerifyCode() throws IOException {
return resourceService.getImgVerifyCode();
}
}
...
Service
public class ResourceService {
@Override
public RestResp<ImgVerifyCodeRespDTO> getImgVerifyCode() throws IOException {
String sessionId = IdWorker.get32UUID();
return RestResp.ok(
ImgVerifyCodeRespDto.builder()
.sessionId(sessionId)
.img(verifyCodeManager.genImgVerifyCode(sessionId))
.build()
);
}
}
public class UserService {
@Override
public RestResp<LoginRespDTO> login() throws IOException {
if (!verifyCodeManager.imgVerifyCodeOk(dto.getSessionId(), dto.getVelCode())) {
throw new BusinessException(ErrorCodeEnum.USER_VERIFY_CODE_ERROR);
}
...
...
verifyCodeManager.removeImgVerifyCode(dto.getSessionId());
}
}
前端显示base64编码的图片
示例代码
<img src="inputImg">
</script>
inputImg = 'data:image/jpeg;base64,' + res.data.body.data
</script>