背景
互联网应用都是前后端分离的,而且一般不会通过session的方式来保持会话,一般都是使用oauth2的方式做登录鉴权。此时,是无法用传统的方式把图片验证码绑定当前会话的方式来做校验的。故可通过以下的方式来做校验。
一 生成图片工具类
1 | import java.awt.*; |
二 Controller获取验证码的方法
方式一: 返回图片流方式1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27/**
* 获取登录图片验证码
*/
"获取图片验证码接口") (value =
"/captcha") (value =
public ResponseEntity<byte[]> getCaptchaCode() {
CaptchaUtil instance = CaptchaUtil.getInstance();
// 验证码标识
String key = "k" + System.currentTimeMillis() + (10000 + new Random().nextInt(89999));
String cacheKey = CacheKeyUtil.getImageValidateCodeCacheKey(key);
redisTemplate.opsForValue().set(cacheKey, instance.getCode(), CacheKeyUtil.DEFAULT_CACHE_TIME, TimeUnit.SECONDS);
// 将图像输出到Servlet输出流中。
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
ImageIO.write(instance.getBuffImg(), "jpeg", out);
return ResponseEntity.status(HttpStatus.OK)
.contentType(MediaType.IMAGE_JPEG)
.header(HttpHeaders.PRAGMA, "no-cache")
.cacheControl(CacheControl.noCache())
.header("CaptchaKey", key)
.header("Access-Control-Expose-Headers", "CaptchaKey")
.body(out.toByteArray());
} catch (IOException e) {
log.error("获取图片验证码异常", e);
throw new RuntimeException("获取图片验证码异常");
}
}
方式二: 返回base64 application/json方式1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21/**
* 获取登录图片验证码
*/
"获取图片验证码base64接口") (value =
"/captcha") (value =
public MsgResult<ValidBase64CodeVO> getCaptchaCode() {
CaptchaUtil instance = CaptchaUtil.getInstance();
// 验证码标识
String key = "k" + System.currentTimeMillis() + (10000 + new Random().nextInt(89999));
String cacheKey = CacheKeyUtil.getImageValidateCodeCacheKey(key);
redisTemplate.opsForValue().set(cacheKey, instance.getCode(), CacheKeyUtil.DEFAULT_CACHE_TIME, TimeUnit.SECONDS);
// 将图像输出到Servlet输出流中。
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
ImageIO.write(instance.getBuffImg(), "jpeg", out);
return this.successHandler(new ValidBase64CodeVO(Base64Utils.encodeToString(out.toByteArray()), "image/jpeg", key));
} catch (IOException e) {
log.error("获取图片验证码异常", e);
throw new CommonRuntimeException(StatusType.FAIL, "获取图片验证码异常");
}
}
ValidBase64CodeVO 类如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* base64的图片验证码
* @author chenxiaoqi
* @since 2021/03/03
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
public class ValidBase64CodeVO {
@ApiModelProperty("base64后的图片验证码")
private String base64;
@ApiModelProperty("图片媒体类型")
private String mediaType;
@ApiModelProperty("图片验证码的key")
private String validateKey;
}
三 方式一响应头中包含的CaptchaKey: k160255833263697219
则是需要在校验验证码的时候一并传入后端的
1 | HTTP/1.1 200 |
校验验证码时需要额外传入的参数如下:
1 | /** |
四 方式一Vue中获取图片验证码同时获取响应头的方式如下:
1 | getValid() { |
五 方式二直接返回body如下
1 | { |
前端在img
的src
属性中填充进data:image/jpeg;base64,
+ body中返回的base64
即可