验证码的设置

news2025/1/14 8:04:03

一、准备环境

首先,进入下载地址:Central Repository: cn/hutool/hutool-all/5.8.16下载jar包

二、配置环境

将下载好的jar包放到eclipse的lib目录 (这里是eclipse软件中存放jar包的目录):

【WebContent-->WEB-INF-->lib】

三、基础方法

(验证码实现的核心就是以下四条方法)

  • createCode 创建验证码,实现类需同时生成随机验证码字符串和验证码图片
  • getCode 获取验证码的文字内容
  • verify 验证验证码是否正确,建议忽略大小写
  • write 将验证码写出到目标流中

LineCaptcha 线段干扰的验证码

//定义图形验证码的长和宽
LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);

//图形验证码写出,可以写出到文件,也可以写出到流
lineCaptcha.write("d:/line.png");
//输出code
Console.log(lineCaptcha.getCode());
//验证图形验证码的有效性,返回boolean值
lineCaptcha.verify("1234");

//重新生成验证码
lineCaptcha.createCode();
lineCaptcha.write("d:/line.png");
//新的验证码
Console.log(lineCaptcha.getCode());
//验证图形验证码的有效性,返回boolean值
lineCaptcha.verify("1234");

CircleCaptcha 圆圈干扰验证码

//定义图形验证码的长、宽、验证码字符数、干扰元素个数
CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(200, 100, 4, 20);
//CircleCaptcha captcha = new CircleCaptcha(200, 100, 4, 20);
//图形验证码写出,可以写出到文件,也可以写出到流
captcha.write("d:/circle.png");
//验证图形验证码的有效性,返回boolean值
captcha.verify("1234");

​​​​​​ShearCaptcha 扭曲干扰验证码

//定义图形验证码的长、宽、验证码字符数、干扰线宽度
ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(200, 100, 4, 4);
//ShearCaptcha captcha = new ShearCaptcha(200, 100, 4, 4);
//图形验证码写出,可以写出到文件,也可以写出到流
captcha.write("d:/shear.png");
//验证图形验证码的有效性,返回boolean值
captcha.verify("1234");

​​​​​​写出到浏览器(Servlet输出)

ICaptcha captcha = ...;
captcha.write(response.getOutputStream());
//Servlet的OutputStream记得自行关闭哦!

自定义验证码

有时候标准的验证码不满足要求,比如我们希望使用纯字母的验证码、纯数字的验证码、加减乘除的验证码,此时我们就要自定义CodeGenerator

// 自定义纯数字的验证码(随机4位数字,可重复)
RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4);
LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);
lineCaptcha.setGenerator(randomGenerator);
// 重新生成code
lineCaptcha.createCode();

前端页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="css/login.css">
    <script src="js/jquery.js"></script>
    <script>
    $(function(){
    	$(".btn").on("click",function(){
    		var a = $(".account").val().trim()
    		var p = $(".password").val().trim()
    		var i = $(".captchaInput").val().trim()
    		var role = $(".role").val().trim()
    		if(a==""){
    			alert("账号不能为空")
    			return
    		}
    		if(p==""){
    			alert("密码不能为空")
    			return
    		}
    		if(i==""){
    			alert("验证码不能为空")
    			return
    		}
    		$.ajax({
    			url:"LoginServlet",
    			type:"get",
    			data:{
    				account:a,
    				password:p,
    				captchaInput: i,
    				role:role,
    			},
    			success:function(value){
    				console.log(value)
    				alert(value.message)
    				if (value.code == 1) {
                            if (role === "admin") {
                                location.href = "main.html";
                            } else if (role === "user") {
                                location.href = "user_main.html";
                            } else if (role === "merchant") {
                            	// 读取商家对应的cookie,这里假设你已经有获取和解析cookie的函数,比如 getCookie 函数
                                var merchantName = getCookie("account");
                                if (merchantName) {
                                    // 根据merchant_id等信息来决定具体跳转的商家页面,这里简单示例为不同id跳转到不同页面,实际可能根据业务逻辑更复杂判断
                                    location.href = "merchant_" + merchantName + ".html";
                                
                            }
                        } else {
                            // 登录失败
                            $(".account").val("");
                            $(".password").val("");
                            $(".captchaInput").val("");
                        }
    			},
    			error:function(){
    				alert("请求失败")
    			}
    		})
    	})
    	
    	
    })
    
    </script>
</head>
<body>
    
    <div class=" container">
        <h2>登录</h2>
        <input type="text" placeholder="请输入账号" class="account">
        <input type="password" placeholder="请输入密码" class="password">
        <div>
            <input type="text" placeholder="请输入验证码" class="captchaInput">
            <img src="CaptchaServlet" class='img'>
        </div>
        <select id='role' name='role' class="role">
           <option value="user">用户</option>
           <option value="admin">管理员</option>
           <option value="merchant">商家</option>
       </select>
        <input type="button" value="登录" class="btn">
        <span>没有账号?<a href="register.html">去注册</a></span>
    </div>
</body>
</html>

css

*{
    padding: 0;
    margin: 0;
}
img{
    width: 45px;
}
body{
    height: 100vh;
    background: linear-gradient(30deg,rgb(47,64,85),rgb(76,132,200));

}
.container{
    width: 20%;
    height: 30vh;
    background: #fff;
    margin: 35vh auto;
    box-sizing: border-box;
    min-width: 200px;
    min-height: 300px;
    border-radius: 30px;
    display: flex;
    flex-direction: column;
    justify-content: space-around;
    padding: 20px;
}
.container h2{
    text-align: center;
    color: rgb(47,64,85);
    font-weight: 500;
}
.container input{
    outline: none;
    border: none;
    border-bottom: 1px solid rgb(47,64,85);
    padding: 4px 6px;
    font-size: 13px;


}
.container div{
    display: flex;
    justify-content: space-between;

}
.container input[type=button]{
    border: none;
    color: #fff;
    border-radius: 20px;
    background: linear-gradient(30deg,rgb(47,64,85),rgb(76,132,200));
    margin-top: 20px;
    cursor: pointer;
}
.container input[type=button]:hover{
    background: linear-gradient(-30deg,rgb(47,64,85),rgb(76,132,200));
}
.container span{
    font-size: 12px;
    color: rgb(47,64,85);
    text-align: center;
    cursor: pointer;

}
.container span a{
    text-decoration: none;
    color: rgb(76,132,200);
    
}

后端处理

package Servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.CircleCaptcha;

/**
 * Servlet implementation class CaptchaServlet
 */
@WebServlet("/CaptchaServlet")
public class CaptchaServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public CaptchaServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//定义图形验证码的长、宽、验证码字符数、干扰元素个数
		
				CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(200, 100, 4, 20);
				//CircleCaptcha captcha = new CircleCaptcha(200, 100, 4, 20);
				//图形验证码写出,可以写出到文件,也可以写出到流
				//captcha.write("d:/circle.png");
				//验证图形验证码的有效性,返回boolean值
				//captcha.verify("1234");
				// 获取当前会话,如果不存在则创建一个新的会话
			    HttpSession session = request.getSession(true);
			    // 将生成的验证码的值保存到会话中,这里假设使用"captchaCode"作为属性名
			    session.setAttribute("captchaCode", captcha.getCode());
				captcha.write(response.getOutputStream());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}
package Servlet;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import db.MysqlUtil;

/**
 * Servlet implementation class LoginServlet
 */
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public LoginServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
	  	response.setCharacterEncoding("utf-8");
	  	response.setContentType("text/json;charset=utf-8");
	 // 获取用户输入的验证码
	  	String userInputCaptcha = request.getParameter("captchaInput");
	 // 获取保存验证码的会话
        HttpSession session = request.getSession(false);
	  	
        if (session!= null) {
            // 从会话中获取之前生成并保存的验证码
            String savedCaptcha = (String) session.getAttribute("captchaCode");

            if (savedCaptcha!= null) {
                // 比较用户输入的验证码和保存的验证码是否一致,忽略大小写
                if (savedCaptcha.equalsIgnoreCase(userInputCaptcha)) {
                    // 验证码验证通过,继续进行账号和密码验证

                    String acc = request.getParameter("account");
                    String pass = request.getParameter("password");
                    String role = request.getParameter("role");
                    System.out.println(acc);
                    System.out.println(pass);
                    System.out.println(role);
                    String sql = "";
                 // 根据不同角色选择不同的数据库表进行查询验证
                    if ("user".equals(role)) {
                        sql = "SELECT * FROM user WHERE account = \"" + acc + "\" and password =\"" + pass + "\"";
                    } else if ("admin".equals(role)) {
                        sql = "SELECT * FROM admin WHERE account = \"" + acc + "\" and password =\"" + pass + "\"";
                    } else if ("merchant".equals(role)) {
                        sql = "SELECT * FROM merchants WHERE account = \"" + acc + "\" and password =\"" + pass + "\"";
                    }

                    int num = MysqlUtil.getCount(sql);
                    System.out.println(num);

                    String res = "{\"code\":0,\"message\":\"登陆失败\"}";
                    if (num > 0) {
                        res = "{\"code\":1,\"message\":\"登陆成功\"}";
                     // 登录成功,设置相关Cookie
                        // 设置标识用户已登录的Cookie,例如名为"isLoggedIn",值为"true"
                        Cookie loggedInCookie = new Cookie("isLoggedIn", "true");
                        // 设置Cookie的有效期,这里设置为1小时(单位是秒),可根据实际需求调整
                        loggedInCookie.setMaxAge(3600);
                        response.addCookie(loggedInCookie);

                        // 设置保存用户账号的Cookie,名为"userAccount",值为用户输入的账号
                        Cookie userAccountCookie = new Cookie("userAccount", acc);
                        userAccountCookie.setMaxAge(3600);
                        response.addCookie(userAccountCookie);
                        
                     // 设置标识用户角色的Cookie,名为"user_role",值为对应的角色
                        Cookie roleCookie = new Cookie("user_role", role);
                        roleCookie.setMaxAge(3600);
                        response.addCookie(roleCookie);
                        if ("merchant".equals(role)) {
                            String idQuerySql = "SELECT merchant_id FROM merchants WHERE account = \"" + acc + "\" and password =\"" + pass + "\"";
                            String nameQuerySql = "SELECT merchant_name FROM merchants WHERE account = \"" + acc + "\" and password =\"" + pass + "\"";
                            Connection conn = null;
                            PreparedStatement pstmt = null;
                            PreparedStatement pstmtName = null;
                            ResultSet rs = null;
                            ResultSet rsName = null;
                            try {
                                // 建立数据库连接(这里假设你已经配置好了数据库连接相关信息,如URL、用户名、密码等)
                                conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/shangcheng", "root", "root");
                                pstmt = conn.prepareStatement(idQuerySql);
                                pstmtName = conn.prepareStatement(nameQuerySql);
                                rs = pstmt.executeQuery();
                                rsName = pstmtName.executeQuery();
                                if (rs.next()&&rsName.next()) {
                                    // 从结果集中获取merchant_id字段的值,假设merchant_id是整型,根据实际类型调整
                                    int merchantId = rs.getInt("merchant_id"); 
                                    String merchantName = rsName.getString("merchant_name");
                                    Cookie merchantIdCookie = new Cookie("merchant_id", String.valueOf(merchantId));
                                    merchantIdCookie.setMaxAge(3600);
                                    response.addCookie(merchantIdCookie);
                                    
                                    Cookie merchantNameCookie = new Cookie("merchant_name", merchantName);
                                    merchantNameCookie.setMaxAge(3600);
                                    response.addCookie(merchantNameCookie);
                                }
                            } catch (SQLException e) {
                                e.printStackTrace();
                            } finally {
                                // 关闭资源,释放连接、语句和结果集对象,避免资源泄漏
                                try {
                                    if (rs!= null) rs.close();
                                    if (pstmt!= null) pstmt.close();
                                    if (conn!= null) conn.close();
                                    if (rsName!= null) rsName.close();
                                    if (pstmtName!= null) pstmtName.close();
                                } catch (SQLException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }    
                    // 返回数据
                    response.getWriter().write(res);
                } else {
                    // 验证码验证不通过,直接返回错误信息
                    String res = "{\"code\": -1, \"message\":\"验证码错误,请重新输入\"}";
                    response.getWriter().write(res);
                }
            } else {
                // 如果从会话中取不到保存的验证码,可能是会话过期等原因,返回相应错误信息
                String res = "{\"code\": -2, \"message\":\"验证码已过期,请重新获取验证码\"}";
                response.getWriter().write(res);
            }
        } else {
            // 如果获取不到会话,可能是客户端未正常建立会话等原因,返回相应错误信息
            String res = "{\"code\": -3, \"message\":\"未获取到会话,请重新操作\"}";
            response.getWriter().write(res);
        }
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

通过CaptchaServlet获取验证码 然后经过LoginServlet进行登录的处理返回给前端页面

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2276377.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FreeCAD集成gmsh源码分析

目录 gmsh模块界面获取gmsh的版本执行gmsh网格划分gmsh模块界面 这个界面是用PySide来写的,Pyside是QT的python绑定,具体代码在task_mesh_gmsh.py文件中。目前这个界面非常的捡漏,没有对接gmsh稍微高级一点的功能。界面对应的事件处理是在gmshtools.py中。这里只分析“gmsh …

忘记了PDF文件的密码,怎么办?

PDF文件可以加密&#xff0c;大家都不陌生&#xff0c;并且大家应该也都知道PDF文件有两种密码&#xff0c;一个打开密码、一个限制编辑密码&#xff0c;因为PDF文件设置了密码&#xff0c;那么打开、编辑PDF文件就会受到限制。忘记了PDF密码该如何解密&#xff1f; PDF和offi…

怎么开通电信跨国网络专线服务?

随着全球化的发展&#xff0c;企业对高效稳定的跨国网络连接需求不断增长。电信跨国网络专线服务凭借其灵活性、安全性和高效性&#xff0c;成为许多企业跨国通信的优选方案。本文将为您详细介绍如何开通这一服务&#xff0c;并分享关键的注意事项&#xff0c;帮助企业更好地利…

MarkDown常用方法

标题 #空格 一级标题 ##空格 二级标题 依次类推 有序列表 操作&#xff1a;数字英文小数点(.)空格示例&#xff1a;1. list12. list2无序列表 操作&#xff1a;- 空格 或 * 空格示例&#xff1a; - list1- list2嵌套有序列表 操作&#xff1a;tab 数字 空格 示例&#xff1a; …

使用gtsam添加OrientedPlane3Factor平面约束因子

在基于地面约束的SLAM优化中&#xff0c;已知的地面信息&#xff08;如 plan.pcd 文件中的地面模型&#xff09;可以用作一个先验约束&#xff0c;以帮助优化位姿估计。具体而言&#xff0c;这个过程涉及将地面模型和每个帧的位姿结合&#xff0c;以创建一个因子模型&#xff0…

二分查找算法——搜索插入位置

一.题目描述 35. 搜索插入位置 - 力扣&#xff08;LeetCode&#xff09; 二.题目解析 如果只看题目的前半句&#xff0c;直接就用简单二分秒了。但是题目还有后半句&#xff0c;如果找不到目标值&#xff0c;则返回它应该插入的位置。 因为数组是排序的&#xff0c;所以应该…

啥!GitHub Copilot也免费使用了

文章目录 前言免费版直接修复代码多文件上下文Agent模式总结 前言 最近&#xff0c;GitHub 给开发者们带来了一个好消息&#xff1a;他们的 AI 编程助手 GitHub Copilot 现在可以免费使用了&#xff01;以前&#xff0c;每个月要花 10 美元才能享受的服务&#xff0c;现在对所…

【计算机网络】窥探计网全貌:说说计算机网络体系结构?

标签难度考察频率综合题⭐⭐⭐60% 这个问题在计算机网络知识体系中是一个比较重要的问题&#xff0c;只有完整地了解计算机网络的体系结构才能清晰地认识网络的运行原理。 在回答这个问题时&#xff0c;笔者认为有几个比较重要的点&#xff1a; 首先一定要分清楚前置条件&am…

Web开发中页面出现乱码的解决(Java Web学习笔记:需在编译时用 -encoding utf-8)

目录 1 引言2 乱码表现、原因分析及解决2.1 乱码表现2.2 原因分析2.3 解决 3 总结 1 引言 Web开发的页面出现了乱码&#xff0c;一直不愿写出来&#xff0c;因为网上的解决方案太多了。但本文的所说的页面乱码问题&#xff0c;则是与网上的大多数解决方案不一样&#xff0c;使…

Cesium小知识:pointPrimitive collection 详解

Cesium.PointPrimitiveCollection 是 Cesium 中用于高效管理和渲染大量点(points)的一个类。它允许你创建和管理大量的 PointPrimitive 实例,这些实例可以用来表示地理空间中的点数据,如传感器位置、车辆位置、兴趣点等。与直接使用 Cesium.Entity 相比,PointPrimitiveCol…

说一说mongodb组合索引的匹配规则

一、背景 有一张1000多万条记录的大表&#xff0c;需要做归档至历史表&#xff0c;出现了大量慢查询。 查询条件是 "classroomId": {$in: ["xxx", "xxx", ..... "xxx","xxx", "xxx" ] }耗时近5秒&#xff0c;且…

【论文笔记】多个大规模数据集上的SOTA绝对位姿回归方法:Reloc3r

abstract 视觉定位旨在确定查询图像相对于姿势图像数据库的相机姿势。 近年来&#xff0c;直接回归相机姿势的深度神经网络由于其快速推理能力而受到欢迎。 然而&#xff0c;现有方法很难很好地推广到新场景或提供准确的相机姿态估计。 为了解决这些问题&#xff0c;我们提出了…

谁在打响整车智能「芯」战役

汽车智能化&#xff0c;显然已经不仅是舱和驾。 尤其是对于算力和智能化来说&#xff0c;即便是已经相对成熟的新能源动力系统&#xff0c;还远未普及。本周&#xff0c;在2025年CES展上&#xff0c;英特尔联合汽车芯片初创公司—Silicon Mobility正式推出面向电动汽车动力总成…

C++ 【从零手撕,模拟实现list类】

1、基础框架 从list源代码中我们可以看到list底层为带哨兵位双向循环链表&#xff0c;从设计者的角度来看&#xff0c;我们并不知道用户在链表中存储的数据类型&#xff0c;所以在这里要使用类模板。再者&#xff0c;每一个节点都包含了前向、后向指针和存储的数据值&#xff0…

gesp(C++五级)(1)洛谷:B3941:[GESP样题 五级] 小杨的锻炼

gesp(C五级)&#xff08;1&#xff09;洛谷&#xff1a;B3941&#xff1a;[GESP样题 五级] 小杨的锻炼 题目描述 小杨的班级里共有 n n n 名同学&#xff0c;每位同学都有各自的锻炼习惯。具体来说&#xff0c;第 i i i 位同学每隔 a i a_i ai​ 天就会进行一次锻炼&#x…

【k8s】scc权限 restricted、anyuid、privileged

文章目录 概述1. 内置的scc2. OpenShift如何确定pod的scc2.1 Pod未带SCC标签的情况2.2. Pod带有SCC标签的情况 参考 概述 在OpenShift&#xff08;后文简称OCP&#xff09;中&#xff0c;很早就一个概念&#xff1a;Security Context Constraints &#xff0c;简称SCC&#xf…

高速光电探测器设计 PIN APD铟镓砷TIA放大脉冲误码测试800-1700nm

高速光电探测器PIN APD铟镓砷TIA放大脉冲误码测试800-1700nm &#xff08;对标:索雷博APD431A&#xff09; &#xff08;对标:索雷博APD431A&#xff09; &#xff08;对标:索雷博APD431A&#xff09; 规格参数: 波长范围:800-1700nm 输出带宽:DC-400MHz&#xff08;-3dB&…

配置 One API + ChatGPT-Next-Web,以讯飞星火认知大模型为例

配置 One API ChatGPT-Next-Web&#xff0c;以讯飞星火认知大模型为例 1.0 One API 配置1.1 获取大模型 API1.2 配置 OneAPI 渠道1.3 配置OneAPI 令牌 2.0 ChatGPT-Next-Web 配置 同步发布在个人笔记配置 One API ChatGPT-Next-Web&#xff0c;以讯飞星火认知大模型为例 上一…

初学者如何保护WordPress网站内容

在如今的数字时代&#xff0c;保护你的WordPress网站内容变得尤为重要&#xff0c;尤其是当你刚刚开始运营自己的网站时。盗版和内容窃取不仅可能影响你的网站流量&#xff0c;还可能损害你的声誉。这篇文章将为初学者介绍几种简单的方法&#xff0c;帮助你有效保护WordPress内…

Maven核心插件之maven-resources-plugin

前言 Maven 插件是 Maven 构建系统的重要组成部分&#xff0c;它们为 Maven 提供了丰富的功能和扩展能力&#xff0c;使得 Maven 不仅是一个构建工具&#xff0c;更是一个强大的项目管理平台。在 Maven 项目中&#xff0c;插件的使用通常通过配置 pom.xml 文件来完成。每个插件…