SpringBoot下实现前端验证码图片的生成和校验,供大家参考,具体内容如下
1.效果
点击验证码可以获取新的验证码
2.原理
后台生成验证码图片,将图片传到前台。
后台在session中保存验证码内容。
前台输入验证码后传到后台在后台取出session中保存的验证码进行校验。
注意,验证码的明文是不能传送到前端的。前端内容都是透明的,不安全。验证码是用来防机器人并不是单单防人。如果把验证码明文传到前端很容易就会被破解。
3.图片生成
验证码生成工具类RandomValidateCodeUtil
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
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 static final Logger logger = LoggerFactory.getLogger(RandomValidateCodeUtil. class );
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);
}
logger.info(randomString);
//将生成的随机字符串保存到session中
session.removeAttribute(RANDOMCODEKEY);
session.setAttribute(RANDOMCODEKEY, randomString);
g.dispose();
try {
// 将内存中的图片通过流动形式输出到客户端
ImageIO.write(image, "JPEG" , response.getOutputStream());
} catch (Exception e) {
logger.error( "将内存中的图片通过流动形式输出到客户端失败>>>> " , e);
}
}
/**
* 绘制字符串
*/
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));
}
}
|
在Controller调用生成验证码图片方法并将图片传到前端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
/**
* 生成验证码
*/
@RequestMapping (value = "/getVerify" )
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) {
logger.error( "获取验证码失败>>>> " , e);
}
}
|
前端获取验证码图片
html
1
2
3
4
5
6
7
8
9
10
11
12
|
< div class = "row" >
< div class = "col-xs-6 pull_left" >
< div class = "form-group" >
< input class = "form-control" type = "tel" id = "verify_input" placeholder = "请输入验证码" maxlength = "4" >
</ div >
</ div >
< div class = "col-xs-6 pull_left" >
< a href = "javascript:void(0);" rel = "external nofollow" title = "点击更换验证码" >
< img id = "imgVerify" src = "" alt = "更换验证码" height = "36" width = "100%" onclick = "getVerify(this);" >
</ a >
</ div >
</ div >
|
js
1
2
3
4
|
//获取验证码
function getVerify(obj){
obj.src = httpurl + "/sys/getVerify?" +Math.random();
}
|
每次点击图片重新刷新验证码
界面初次加载时,调用getVerify()方法即可。
4.验证码验证
前端获取用户输入的验证码,传到后台进行验证。
后台验证代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
/**
* 忘记密码页面校验验证码
*/
@RequestMapping (value = "/checkVerify" , method = RequestMethod.POST, headers = "Accept=application/json" )
public boolean checkVerify( @RequestBody Map<String, Object> requestMap, HttpSession session) {
try {
//从session中获取随机数
String inputStr = requestMap.get( "inputStr" ).toString();
String random = (String) session.getAttribute( "RANDOMVALIDATECODEKEY" );
if (random == null ) {
return false ;
}
if (random.equals(inputStr)) {
return true ;
} else {
return false ;
}
} catch (Exception e){
logger.error( "验证码校验失败" , e);
return false ;
}
}
|
后台校验后,返给前端验证结果true或者false即可。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:http://blog.csdn.net/colton_null/article/details/78744240