验证码技术实现

简介:

    对于一些恶意强暴破解密码的行为(即通过硬性尝试用户名密码进行破解),可以采用验证码对其进行抵御,对于一些程序可以识别验证码,则需要对验证码形式进行多样化设计。


用户登录时设置验证码代码实现:

  1. 页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<script type= "text/javascript" >
function _change() {
 
var imgEle = document.getElementById( "img" );
imgEle.src =  "${pageContext.request.contextPath }/user_getVerify.action?a=" 
new  Date().getTime();
}
</script>
<BODY>
<FORM id=form1 name=form1 action= "${pageContext.request.contextPath }/user_login.action"  method= "post" >
<TR>
                 <TD style= "HEIGHT: 28px" >验证码:</TD>
                 <TD style= "HEIGHT: 28px" >
                 <input type= "text"  name= "verifyCode"  size= "1" />
                     <img id= "img"  src= "${pageContext.request.contextPath }/user_getVerify.action" >
                 <br/>
                 <a href= "javascript:_change()" >换一张</a>
                 </TD>
                   <a href= "#" ></a>
                 <TD style= "HEIGHT: 28px" ><SPAN id=RequiredFieldValidator4 
                   style= "FONT-WEIGHT: bold; VISIBILITY: hidden; COLOR: white" >请输入验证码</SPAN></TD></TR>
         
               <TR>
</FORM></BODY>


2.action操作

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
     //获得验证码
     public  void  getVerify()  throws  IOException{
         HttpServletRequest request=ServletActionContext.getRequest();
         HttpServletResponse response=ServletActionContext.getResponse();
         VerifyCode vc= new  VerifyCode();
         BufferedImage image=vc.getImage(); //获得图片
         request.getSession().setAttribute( "session_vcode" ,vc.getText()); //将验证码内容放在域对象里面
         VerifyCode.output(image, response.getOutputStream());
     }
     
     public  String login(){
         HttpServletRequest request=ServletActionContext.getRequest();
         String sessionCode = (String) request.getSession().getAttribute( "session_vcode" );
         String paramCode = request.getParameter( "verifyCode" );
         if (!paramCode.equalsIgnoreCase(sessionCode)){
             request.setAttribute( "msg" "验证码错误!" );
             return  "login" ;
         }
         
         User userExit=userService.login(user);
         if (userExit!= null ){
             if (!userExit.isState())
             {
                 request.setAttribute( "msg" "您尚未激活,请到邮箱" +userExit.getEmail()+ "激活!" );
                 return  "loginerror" ;
             }
             request=ServletActionContext.getRequest();
             request.getSession().setAttribute( "user" , userExit);
             return  "loginsuccess" ;
         } else {
             return  "login" ;
         }
     }


3.验证码代码实现

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
import  java.awt.BasicStroke;
import  java.awt.Color;
import  java.awt.Font;
import  java.awt.Graphics2D;
import  java.awt.image.BufferedImage;
import  java.io.IOException;
import  java.io.OutputStream;
import  java.util.Random;
import  javax.imageio.ImageIO;
 
public  class  VerifyCode {
     private  int  w =  70 ;
     private  int  h =  35 ;
    private  Random r =  new  Random();
    // {"宋体", "华文楷体", "黑体", "华文新魏", "华文隶书", "微软雅黑", "楷体_GB2312"}
     private  String[] fontNames  = { "宋体" "华文楷体" "黑体" "微软雅黑" "楷体_GB2312" };
     // 可选字符
     private  String codes  =  "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ" ;
     // 背景色
     private  Color bgColor  =  new  Color( 255 255 255 );
     // 验证码上的文本
     private  String text ;
     
     // 生成随机的颜色
     private  Color randomColor () {
         int  red = r.nextInt( 150 );
         int  green = r.nextInt( 150 );
         int  blue = r.nextInt( 150 );
         return  new  Color(red, green, blue);
     }
     // 生成随机的字体
     private  Font randomFont () {
         int  index = r.nextInt(fontNames.length);
         String fontName = fontNames[index]; //生成随机的字体名称
         int  style = r.nextInt( 4 ); //生成随机的样式, 0(无样式), 1(粗体), 2(斜体), 3(粗体+斜体)
         int  size = r.nextInt( 5 ) +  24 //生成随机字号, 24 ~ 28
         return  new  Font(fontName, style, size);
     }
     
     // 画干扰线
     private  void  drawLine (BufferedImage image) {
         int  num  =  3 ; //一共画3条
         Graphics2D g2 = (Graphics2D)image.getGraphics();
         for ( int  i =  0 ; i < num; i++) { //生成两个点的坐标,即4个值
             int  x1 = r.nextInt(w);
             int  y1 = r.nextInt(h);
             int  x2 = r.nextInt(w);
             int  y2 = r.nextInt(h); 
             g2.setStroke( new  BasicStroke( 1 .5F)); 
             g2.setColor(Color.BLUE);  //干扰线是蓝色
             g2.drawLine(x1, y1, x2, y2); //画线
         }
     }
     // 随机生成一个字符
     private  char  randomChar () {
         int  index = r.nextInt(codes.length());
         return  codes.charAt(index);
     }
     
     // 创建BufferedImage
     private  BufferedImage createImage () {
         BufferedImage image =  new  BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 
         Graphics2D g2 = (Graphics2D)image.getGraphics(); 
         g2.setColor( this .bgColor);
         g2.fillRect( 0 0 , w, h);
        return  image;
     }
     // 调用这个方法得到验证码
     public  BufferedImage getImage () {
         BufferedImage image = createImage(); //创建图片缓冲区 
         Graphics2D g2 = (Graphics2D)image.getGraphics(); //得到绘制环境
         StringBuilder sb =  new  StringBuilder(); //用来装载生成的验证码文本
         // 向图片中画4个字符
         for ( int  i =  0 ; i <  4 ; i++)  { //循环四次,每次生成一个字符
             String s = randomChar() +  "" ; //随机生成一个字母 
             sb.append(s);  //把字母添加到sb中
             float  x = i *  1 .0F * w /  4 //设置当前字符的x轴坐标
             g2.setFont(randomFont());  //设置随机字体
             g2.setColor(randomColor());  //设置随机颜色
             g2.drawString(s, x, h- 5 );  //画图
         }
         this .text = sb.toString();  //把生成的字符串赋给了this.text
         drawLine(image);  //添加干扰线
         return  image;     
     }
     
     // 返回验证码图片上的文本
     public  String getText () {
         return  text;
     }
     // 保存图片到指定的输出流
     public  static  void  output (BufferedImage image, OutputStream out) 
                 throws  IOException {
         ImageIO.write(image,  "JPEG" , out);
     }
}

4.效果

wKioL1kis9OyAWbjAAASc0DQcu4395.jpg-wh_50


本文转自 叫我北北 51CTO博客,原文链接:http://blog.51cto.com/qinbin/1928345

相关文章
|
7月前
|
C++
|
7月前
生成验证码
生成验证码
44 0
|
缓存 前端开发 NoSQL
南南的文章-验证码还能这样生成?
南南的文章-验证码还能这样生成?
85 0
南南的文章-验证码还能这样生成?
|
缓存 JavaScript 安全
|
机器学习/深度学习 人工智能 前端开发
关于验证码,你不知道的一些问题!
关于验证码,大家也许会有很多疑问,下面我总结了一些常见问题。
关于验证码,你不知道的一些问题!
|
前端开发 C# 数据安全/隐私保护
C#验证码
验证码通常是为了区分用户是人还是计算机,也可以防止破解密码、刷票等恶意行为,而客户端上多数会用在关键操作上,比如购买、登录、注册等场景。现在验证码的种类样式也特别多,今天教大家如何用C#做出滑动拼图验证码吧~
C#验证码
|
JavaScript 前端开发
简单的验证码功能
简单的验证码功能
简单的验证码功能
|
Web App开发 Java
|
C# 图形学 索引