注意 前端vue调用的时候 不要使用 localhost 要在 host里面设置一下域名才行 要不然获取验证码获取不到会!!!!!!
不说废话 直接上代码 。
Controller 层
/**
* 生成验证码
*/
@ApiOperation(value = "生成验证码")
@RequestMapping(value = "/Verify")
public void getVerify(HttpServletRequest request, HttpServletResponse response) {
try {
response.setContentType("image/jpeg");//设置相应类型,告诉浏览器输出的内容为图片
response.setHeader("Pragma", "No-cache");//设置响应头信息,告诉浏览器不要缓存此内容
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expire", 0);
RandomValidateCodeUtil randomValidateCode = new RandomValidateCodeUtil();
randomValidateCode.getRandcode(request, response);//输出验证码图片方法
} catch (Exception e) {
System.out.println("获取验证码失败>>>> ");
}
}
校验验证码 注意下面为单纯校验验证码功能, 要结合到自己的登录接口一起使用 只需要简单修改自己的登录就可。
/**
* 校验验证码
*/
@ApiOperation(value = "校验验证码")
@RequestMapping(value = "/checkVerify", method = RequestMethod.POST)
@ResponseBody
public CommonResult<Map<String,Object>> checkVerify(@RequestBody Map verifyInput, HttpSession session) {
Map<String,Object> map = new HashMap<>();
try{
//从session中获取随机数
String inputStr = verifyInput.get("verifyinput").toString();
String random = (String) session.getAttribute("RANDOMVALIDATECODEKEY");
if (random == null) {
map.put("code",400);
map.put("msg","没有获取到验证码");
map.put("success",false);
return CommonResult.success(map);
}
if (random.equals(inputStr)) {
map.put("code",200);
map.put("msg","验证码匹配成功");
map.put("success",true);
return CommonResult.success(map);
} else {
map.put("code",400);
map.put("msg","验证码不匹配");
map.put("success",false);
return CommonResult.success(map);
}
}catch (Exception e){
map.put("code",400);
map.put("msg","验证码异常");
map.put("success",false);
return CommonResult.success(map);
}
}
RandomValidateCodeUtil.java 公共生成验证码方法
public class RandomValidateCodeUtil {
public static final String RANDOMCODEKEY= "RANDOMVALIDATECODEKEY";//放到session中的key
private String randString = "0123456789";//随机产生只有数字的字符串 private String
//private String randString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";//随机产生只有字母的字符串
//private String randString = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";//随机产生数字与字母组合的字符串
private int width = 95;// 图片宽
private int height = 25;// 图片高
private int lineSize = 40;// 干扰线数量
private int stringNum = 4;// 随机产生字符数量
private Random random = new Random();
/**
* 获得字体
*/
private Font getFont() {
return new Font("Fixedsys", Font.CENTER_BASELINE, 18);
}
/**
* 获得颜色
*/
private Color getRandColor(int fc, int bc) {
if (fc > 255)
fc = 255;
if (bc > 255)
bc = 255;
int r = fc + random.nextInt(bc - fc - 16);
int g = fc + random.nextInt(bc - fc - 14);
int b = fc + random.nextInt(bc - fc - 18);
return new Color(r, g, b);
}
/**
* 生成随机图片
*/
public void getRandcode(HttpServletRequest request, HttpServletResponse response) {
HttpSession session = request.getSession();
// BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
Graphics g = image.getGraphics();// 产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作
g.fillRect(0, 0, width, height);//图片大小
g.setFont(new Font("Times New Roman", Font.ROMAN_BASELINE, 18));//字体大小
g.setColor(getRandColor(110, 133));//字体颜色
// 绘制干扰线
for (int i = 0; i <= lineSize; i++) {
drowLine(g);
}
// 绘制随机字符
String randomString = "";
for (int i = 1; i <= stringNum; i++) {
randomString = drowString(g, randomString, i);
}
//将生成的随机字符串保存到session中
// request.getSession().removeAttribute(RANDOMCODEKEY);
// request.getSession().setAttribute(RANDOMCODEKEY, randomString);
session.removeAttribute(RANDOMCODEKEY);
session.setAttribute(RANDOMCODEKEY, randomString);
g.dispose();
try {
// 将内存中的图片通过流动形式输出到客户端
ImageIO.write(image, "JPEG", response.getOutputStream());
} catch (Exception e) {
System.out.println("将内存中的图片通过流动形式输出到客户端失败>>>> ");
}
}
/**
* 绘制字符串
*/
private String drowString(Graphics g, String randomString, int i) {
g.setFont(getFont());
g.setColor(new Color(random.nextInt(101), random.nextInt(111), random
.nextInt(121)));
String rand = String.valueOf(getRandomString(random.nextInt(randString
.length())));
randomString += rand;
g.translate(random.nextInt(3), random.nextInt(3));
g.drawString(rand, 13 * i, 16);
return randomString;
}
/**
* 绘制干扰线
*/
private void drowLine(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 String getRandomString(int num) {
return String.valueOf(randString.charAt(num));
}
}
前端为vue +axios + element 使用 下面为调用示例代码
这里设置axios 请求跨session
调用验证码的地方要设置 responseType 为 blob
图片直接声明一个变量 getVerfyCode 方便赋值
我的blob 在res.data 里面 直接 这样声明一下src 赋值给 getVerfyCode 在created()
初始化执行一下 就可以获取到验证码啦
验证流程为
1,后端生成验证码图片流 并网请求的request 里面插入 session数据 返回给前端,
2,前端拿取到图片流进行展示 ,并输入账号密码验证码调用后台接口。
3,后台接口根据请求的request 获取里面正确的session 验证码进行验证 匹配
前端传入的code验证码 通过验证码就进行判断账号密码就可以啦 !