javaweb登录验证码的实现方法

下面是“JavaWeb登录验证码的实现方法”的详细攻略:

下面是“JavaWeb登录验证码的实现方法”的详细攻略:

什么是验证码

验证码(Verification Code)是一种用于判断用户是否为人类的简单程序,主要目的是防止恶意程序对网站进行暴力破解或网络爬虫行为。常见的验证码包括数字、字母、图片、数学公式等形式,验证码输入错误时,通常会跳出提示框要求重新输入。

JavaWeb登录验证码的实现方法

JavaWeb登录验证码的实现方法主要分为以下两种:

使用JSP内置对象生成验证码

步骤一:创建JSP页面

在项目的webapp文件夹下创建login.jsp页面,并在该页面中添加以下代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
    <form action="loginServlet" method="post">
        用户名:<input type="text" name="username"><br>
        密码:<input type="password" name="password"><br>
        验证码:<input type="text" name="checkCode"><br>
        <img src="<%=request.getContextPath()%>/checkCodeServlet" />
        <input type="submit" value="登录">
    </form>
</body>
</html>

以上代码中,<img>标签中的src属性的值为生成验证码的Servlet地址,代码的详细解释见下文。

步骤二:生成验证码的Servlet

在项目的src文件夹下创建CheckCodeServlet.java文件,并在该文件中添加以下代码:

package com.example.servlet;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
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 CheckCodeServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public CheckCodeServlet() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 禁止页面缓存
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        // 设置响应内容类型及编码
        response.setContentType("image/jpeg;charset=utf-8");

        // 验证码图片的宽度和高度
        int width = 100, height = 35;
        // 创建内存图片对象
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 获取绘图对象
        Graphics g = image.getGraphics();
        // 设置背景色
        g.setColor(Color.WHITE);
        // 填充矩形
        g.fillRect(0, 0, width, height);

        // 生成随机数字
        StringBuffer sb = new StringBuffer();
        Random random = new Random();
        for (int i = 0; i < 4; i++) {
            int x = random.nextInt(10);
            sb.append(x);
        }

        // 将验证码存入Session
        request.getSession().setAttribute("checkCode", sb.toString());

        // 设置字体
        g.setFont(new Font("宋体", Font.BOLD, 20));
        // 设置颜色
        g.setColor(Color.BLACK);
        // 绘制数字
        g.drawString(sb.toString(), 30, 25);
        // 绘制干扰线
        for (int i = 0; i < 6; i++) {
            int x1 = random.nextInt(width);
            int y1 = random.nextInt(height);
            int x2 = random.nextInt(width);
            int y2 = random.nextInt(height);
            g.setColor(new Color(random.nextInt(256), random.nextInt(256),  random.nextInt(256)));
            g.drawLine(x1, y1, x2, y2);
        }

        // 输出图片
        ImageIO.write(image, "JPEG", response.getOutputStream());
    }
}

以上方法中,利用java.awt提供的工具类,创建内存中的图片对象,利用绘图对象将生成的验证码和干扰线绘制到图片上,然后使用流输出图片。

步骤三:验证验证码正确性的Servlet

在项目的src文件夹下创建LoginServlet.java文件,并在该文件中添加以下代码:

package com.example.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public LoginServlet() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 获取用户输入的验证码
        String checkCode = request.getParameter("checkCode");
        // 获取Session中的验证码
        String sessionCheckCode = (String) request.getSession().getAttribute("checkCode");
        // 判断验证码是否正确
        if (checkCode != null && checkCode.equalsIgnoreCase(sessionCheckCode)) {
            // 验证码正确,进行登录操作
            // ...
        } else {
            // 验证码不正确,返回登录页面
        }
    }
}

以上代码从请求参数中获取用户输入的验证码,并从Session中获取保存的验证码,之后进行比较,以判断验证码的正确性。如果正确,继续进行登录操作;如果不正确,则返回登录页面。

使用第三方库生成验证码

除了使用JSP内置对象生成验证码之外,还可以使用第三方开源库,比如Google的kaptcha进行验证码的生成。

步骤一:导入kaptcha依赖

在项目的pom.xml文件中,添加kaptcha依赖:

<dependency>
    <groupId>com.github.penggle</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3.2</version>
</dependency>

步骤二:生成验证码的Servlet

在项目的src文件夹下创建KaptchaServlet.java文件,并在该文件中添加以下代码:

package com.example.servlet;

import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.code.kaptcha.impl.DefaultKaptcha;

public class KaptchaServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    private DefaultKaptcha kaptcha = new DefaultKaptcha();

    public KaptchaServlet() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 禁止页面缓存
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        // 设置响应内容类型及编码
        response.setContentType("image/jpeg;charset=utf-8");

        // 生成验证码
        String text = kaptcha.createText();
        // 将验证码存入Session
        request.getSession().setAttribute("kaptcha_text", text);
        // 创建验证码图片
        BufferedImage image = kaptcha.createImage(text);
        // 输出图片
        ImageIO.write(image, "JPEG", response.getOutputStream());
    }
}

以上代码使用kaptcha库的DefaultKaptcha类生成验证码,并将验证码保存在Session中。由于kaptcha库自带干扰线的绘制,所以无需手动绘制干扰线。

步骤三:验证验证码正确性的Servlet

在项目的src文件夹下创建LoginServlet.java文件,并在该文件中添加以下代码:

package com.example.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public LoginServlet() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 获取用户输入的验证码
        String kaptcha_text = request.getParameter("kaptcha_text");
        // 获取Session中的验证码
        String sessionKaptchaText = (String) request.getSession().getAttribute("kaptcha_text");
        // 判断验证码是否正确
        if (kaptcha_text != null && kaptcha_text.equalsIgnoreCase(sessionKaptchaText)) {
            // 验证码正确,进行登录操作
            // ...
        } else {
            // 验证码不正确,返回登录页面
        }
    }
}

以上代码从请求参数中获取用户输入的验证码,并从Session中获取保存的验证码,之后进行比较,以判断验证码的正确性。如果正确,继续进行登录操作;如果不正确,则返回登录页面。

总结

本文介绍了JavaWeb登录验证码的两种实现方法:使用JSP内置对象生成验证码和使用第三方库生成验证码。它们各有优缺点,开发者可以根据实际需要进行选择。无论使用哪种方法,都需要注意保证验证码的随机性、不易被破解,并在代码中防止Session劫持和CSRF攻击。

本文标题为:javaweb登录验证码的实现方法

基础教程推荐