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