一.什么是验证码及它的作用
验证码为全自动区分计算机和人类的图灵测试的缩写,是一种区分用户是计算机的公共全自动程序,这个问题可以由计算机生成并评判,但是必须只有人类才能解答. 可以防止恶意破解密码、刷票、论坛灌水、有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登录。
二.图文验证码的原理
在 servlet中随机生成一个指定位置的验证码,一般为四位,然后把该验证码保存到session中.在通过Java的绘图类以图片的形式输出该验证码。 为了增加验证码的安全级别,可以输出图片的同时输出干扰线,最后在用户提交数据的时候,在服务器端将用户提交的验证码和Session保存的验证码进行比 较。
三.验证码所需的技术
i.因为验证码中的文字,数字,应为都是可变的,故要用到随机生成数技术。
ii.如果验证码中包含汉字,则要用到汉字生成技术.
iii.可以使用Ajax技术实现局部刷新
iv.可以使用图片的缩放和旋转技术,
vi.随机绘制干扰线(可以是折现,直线等)
vii.如果考虑到验证码的安全性,可以使用MD5加密.
操作代码有流程
1.代码先新建UserServlet.java也就是servlet文件
package controller; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.PrintWriter; import java.util.Random; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class UseryanServlet extends HttpServlet { //定义一个方法可以获取到a-z或A-Z或0-9的ASCII码值的随机数 public int ro() { int b = 0; Random r = new Random(); while (true) { int a = (int) (r.nextDouble() * 123); if ((a >= 'a' && a <= 'z') || (a >= 'A' && a <= 'Z') || (a > 47 && a < 58)) { b = a; break; } } return b; } public UseryanServlet() { super(); } /** * Destruction of the servlet. <br> */ public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 定义大小的值 int width = 120, height = 25; // 在内存产生一个图片 BufferedImage bimage = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR); //得到画笔 Graphics g = bimage.getGraphics(); //一个矩形 g.setColor(Color.blue); g.drawRect(0, 0, width, height); //画填充背景 g.setColor(Color.red); g.drawRect(1, 1, width - 2, height - 2); //画干扰线条 20条 g.setColor(Color.gray); Random r = new Random(); for (int i = 1; i < 20; i++) { g.drawLine(r.nextInt(width), r.nextInt(height), r.nextInt(width), r.nextInt(height)); } // 画随机数字 g.setColor(Color.yellow); g.setFont(new Font("黑体", Font.BOLD | Font.ITALIC, 20)); String code = "";//生成的随机数返回到code // 生产4个随机数字 for (int i = 0; i < 4; i++) { char a = (char)ro(); code += a+""; g.drawString(a + "", 20 * i, 20); } request.getSession().setAttribute("captcha", code);//获取验证码到UserLoginServlet进行验证 // 输出图像到页面 response.setContentType("image/jpeg"); ImageIO.write(bimage, "jpg", response.getOutputStream()); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } public void init() throws ServletException { super.init(); } }
2.在登录的UserLoginServlet对输入的验证码进行判断
String captcha = (String) request.getSession().getAttribute("captcha"); if(!captcha.equalsIgnoreCase(newCaptcha)) { request.setAttribute("errorMsg", "验证码输入错误"); request.getRequestDispatcher("/WEB-INF/jsp/error.jsp").forward(request, response); return; }
3..在web.xml文件找到对应的UseryanServlet方法
<servlet-mapping>
<servlet-name>UseryanServlet</servlet-name>
<url-pattern>/UseryanServlet</url-pattern>
</servlet-mapping>
4.在登录首页进行设置
<input name="captcha" type="text" placeholder="验证码"><img src="UseryanServlet"></td>
name="captcha"输入到UserLoginServlet对验证码进行判断后的String captcha = (String) request.getSession().getAttribute("captcha");
后台的验证码通过src="UseryanServlet"获取 在web.xml文件找到对应的UseryanServlet方法,
判断正确才允许登录。