网页登录时验证码功能的实现

article/2025/10/13 3:47:20

网页登录时验证码功能的实现

  • 在我们日常上网时,经常会遇到要登录的界面,我们会发现他会让你输入账号,密码外,还需要输入随机生成的验证码。

  • 作用: 不少网站为了防止用户利用机器人自动注册、登录、灌水,都采用了验证码技术。所谓验证码,就是将一串随机产生的数字或符号,生成一幅图片,图片里加上一些干扰象素(防止OCR),由用户肉眼识别其中的验证码信息,输入表单提交网站验证,验证成功后才能使用某项功能。

  • 效果如下图所示:
    在这里插入图片描述

  • 点击图片或刷新页面,都可以刷新验证码图片。下面就为大家讲解这个功是如何实现的。

  • 在这里说明一下,针对这个功能的实现,我是在后端使用Java语言生成图像的方式来实现。我对其实现的代码进行了封装,将其做成一个工具类。以便再其他场景的使用,和代码移植的便捷性。

  • 以下就是该工具类:

  • ImageUtils类

package com.wdhcr.tools;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import java.util.Random;/** 实现获取验证码图像功能的工具类* 返回一个BufferedImage对象** */
public class ImageUtils {// 随机字符集合中去除掉了0和o,O,1和l,因为这些不易区分private static String CHECK_CODES = "abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789";//  该方法主要作用是生成随机的颜色private static Color getRandColor(int s, int e) {Random random = new Random();if (s > 255)s = 255;if (e > 255)e = 255;int r, g, b;r = s + random.nextInt(e - s); // 随机生成RGB颜色中的r值g = s + random.nextInt(e - s); // 随机生成RGB颜色中的g值b = s + random.nextInt(e - s); // 随机生成RGB颜色中的b值return new Color(r, g, b);}/*@param:width , height 指定生成验证码的宽度和高度HttpServletRequest request 传入需要获取验证码图片的会话请求,将验证码四位验证码放入到session域中@return:BufferedImage image对象*/public static BufferedImage getPicture(int width, int height, HttpServletRequest request) {// 创建BufferedImage对象,其作用相当于一图片BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);Graphics g = image.getGraphics(); // 创建Graphics对象,其作用相当于画笔Graphics2D g2d = (Graphics2D) g; // 创建Grapchics2D对象Random random = new Random();Font mfont = new Font("幼圆", Font.BOLD, 25); // 定义字体样式,显示大小g.setColor(getRandColor(200, 250));g.fillRect(0, 0, width, height); // 绘制背景图片大小g.setFont(mfont); // 设置字体g.setColor(getRandColor(180, 200));// 绘制50条颜色和位置全部为随机产生的线条,该线条为2ffor (int i = 0; i < 50; i++) {int x = random.nextInt(width - 1);int y = random.nextInt(height - 1);int x1 = random.nextInt(6) + 1;int y1 = random.nextInt(12) + 1;BasicStroke bs = new BasicStroke(2f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL); // 定制线条样式Line2D line = new Line2D.Double(x, y, x + x1, y + y1);g2d.setStroke(bs);g2d.draw(line); // 绘制直线}//用来保存验证码字符串文本内容StringBuilder sb = new StringBuilder();for (int i = 0; i < 4; ++i) {// 随机生成4个字符/*random.nextInt(CHECK_CODES.length())使用这个方法获取到一个从0到CHECK_CODES.length()*包含0,不包含    CHECK_CODES.length()的一个随机数*使用charAt根据下标的方式取出字符。*/char charAt = CHECK_CODES.charAt(random.nextInt(CHECK_CODES.length()));String sTemp = String.valueOf(charAt);sb.append(sTemp);Color color = new Color(20 + random.nextInt(110), 20 + random.nextInt(110), random.nextInt(110));g.setColor(color);// 将生成的随机数进行随机缩放并旋转制定角度 PS.建议不要对文字进行缩放与旋转,因为这样图片可能不正常显示/* 将文字旋转制定角度 */Graphics2D g2d_word = (Graphics2D) g;AffineTransform trans = new AffineTransform();trans.rotate((45) * 3.14 / 180, 15 * i + 8, 7);/* 缩放文字 */float scaleSize = random.nextFloat() + 0.8f;if (scaleSize > 1f)scaleSize = 1f;trans.scale(scaleSize, scaleSize);g2d_word.setTransform(trans);g.drawString(sTemp, 15 * i + 18, 14);}/** 将生成的四位随机验证码,放入session域中,方便登录controller的获取,验证。*当有controller调用获取验证码工具类时,需要传入本次请求的会话request,并获取session域。将验证码数据放入其中。* */HttpSession session = request.getSession(true);session.setAttribute("randCheckCode", sb.toString());System.out.println("sRand=" + sb.toString());g.dispose(); // 释放g所占用的系统资源//返回画布return image;}}
  • controller层类,接收到前端请求
package com.wdhcr.controller;import com.wdhcr.tools.ImageUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;@Controller
public class CheckController {/** 当页面请求时,使用画布获取一个验证码图像* 返回到页面* 接收前端获取验证码的请求,使用画布随机生成一个四位数的验证码图像* 将生成的四位数字,数字或字母放在一个session域中使得登录验证的controller中可以获取到该值,判断登陆验证* 使用mageIO.write(image, "JPEG", response.getOutputStream());输出图片* 使其再前端可以接收再图片显示出来* */@RequestMapping(value = "/checkCode")public void checkCode(HttpServletRequest request, HttpServletResponse response) throws IOException {//设置编码格式request.setCharacterEncoding("UTF-8");response.setCharacterEncoding("UTF-8");// 设置不缓存图片response.setHeader("Pragma", "No-cache");response.setHeader("Cache-Control", "No-cache");response.setDateHeader("Expires", 0);// 指定生成的响应图片,一定不能缺少这句话,否则错误.response.setContentType("image/jpeg");/** @param* 传入生成图像长度和宽度,还有本次会话的请求HttpServletRequest对象request* @return* 返回一个BufferedImage对象* */BufferedImage image = ImageUtils.getPicture(80, 35, request);// 将图像输出到response输出流中。//response.getOutputStream()获取response输出流ImageIO.write(image, "JPEG", response.getOutputStream()); // 输出图片}
}
  • 前端html或jsp页面代码
<div class="control-group"><label class="control-label visible-ie8 visible-ie9">验证码</label><div class="controls"><div class="input-icon left"><i class="icon-book"></i><%--                    这里是输入验证码图片中的字符,传入后台进行验证--%><input style="width:49%;float:left;height: 24px;" type="text" placeholder="验证码" name="check"id="check"/><span style="cursor:pointer;float: right;height: 34px; width: 30%;">
<%--                        这里需要注意src的路径,为controller层指定的路径@RequestMapping(value = "/checkCode")的路径--%>
<%--                        Reload()方法实现点击一次请求一次后台controller--%><img id="CreateCheckCode" style="width: 100%;height:100%;" src="checkCode.do" onclick="Reload()" /></span></div></div></div>
  • 这里的前端代码主要实现功能的是

      <%-- 这里是输入验证码图片中的字符,传入后台进行验证--%><input style="width:49%;float:left;height: 24px;" type="text" placeholder="验证码" name="check"id="check"/><span style="cursor:pointer;float: right;height: 34px; width: 30%;"><%-- 这里需要注意src的路径,为controller层指定的路径@RequestMapping(value = 	"/checkCode")的路径--%><%--Reload()方法实现点击一次请求一次后台controller--%><img id="CreateCheckCode" style="width: 100%;height:100%;" src="checkCode.do"onclick="Reload()"/>
    
  • 实现点击换验证码图片的js代码

    <!-- 验证码图片点击切换 --><!-- 通过Date来改变每次访问的url不同 -->
<script>function Reload() {document.getElementById("CreateCheckCode").src =// 获取当前时间使其请求不重复document.getElementById("CreateCheckCode").src + "?nocache=" + new Date().getTime() + ".do";}</script>
  • 在工具类中我将四位字符放到了本次会话的session域中,所以在登录的controller验证时加入如下代码:
//创建session域的对象,获取域中的数据if (session.getAttribute("randCheckCode").toString().equalsIgnoreCase(check)) {try {//验证成功后,转发到index页面request.getRequestDispatcher("index.jsp").forward(request, response);} catch (ServletException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}else {//验证码输入错误,弹窗提示,并返回到login页面writer.println("<script>alert('登录失败了!验证码错误!!!');</script>");}
  • 以上就是登录时验证码功能实现的步骤以及源码。

http://chatgpt.dhexx.cn/article/TcY3Njid.shtml

相关文章

登录验证码(前后端分离、不分离)

1.简介  Java图形验证码&#xff0c;支持gif、中文、算术等类型&#xff0c;可用于Java Web、JavaSE等项目。 2.效果展示 3.导入项目 3.1.gradle方式的引入 dependencies {compile com.github.whvcse:easy-captcha:1.6.2 }3.2.maven方式引入 <dependencies><dep…

JavaScript入门一(JS基础知识)

文章目录 一、JavaScript是什么二、网页组成三、什么是JS引擎四、JavaScript特点五、JavaScript的组成六、JavaScript的引用方式1、行内嵌入式2、页内嵌入式3、外部式&#xff08;外链式&#xff09; 七、变量1、什么是变量2、变量的命名规则3、变量的定义方式4、变量的使用 八…

JS逆向需要掌握的JS基础知识与前端知识

本文将会把我平时在JS逆向中遇到的一些JS基础知识和遇到的问题写在这里。&#xff08;比较杂&#xff09; JS逆向需要掌握JS基础知识 nodejs和v8引擎的关系NodeJS环境和浏览器环境执行JS代码区别 webpackJS逆向中常见的window.webpackJsonp分析 JS基础语法声明时用"var&qu…

Vue.js基础知识点总结

Vue基础总结 邂逅Vuejs 1.认识Vuejs Vue是一个渐进式框架, 什么是渐进式的呢? 声明式渲染→组件系统→客户端路由→集中式状态管理→项目构建渐进式意味着你可以将Vue作为你应用的一部分嵌入其中&#xff0c;带来更丰富的交互体验。 Vue有很多特点和Web开发中常见的高级功能…

JavaScript基础知识总结笔记

一、js的两种引入方式 1.<script type"text/javascript"> 自己编写的js代码 </script> 将上面的代码放在<head></head>或者<body></body>之间 2.直接保存为js文件&#xff0c;然后外部调用<script type"text/java…

JavaScript 基础知识总结(一)

这是近期学习JavaScript基础知识的学习笔记 目前在学习Web API&#xff0c;学习途中有时间的话也会发一发自己的心得吧 一.Java Script简介 JS分为三部分&#xff1a; 而学习的java script基本语法属于ECMAScript 二.书写位置 与CSS相同&#xff0c;JS的书写位置也有如下…

JavaScript基础知识总结(1)

hello小伙伴们&#xff0c;本期来更新一下JavaScript基础知识&#xff0c;当做对JS的复习。 之前更新的有CSS复习和HTML复习&#xff0c;在这里放上链接 前端大厂面试笔记&#xff08;二&#xff09;&#xff08;持续更~~&#xff09;_Ss、、帅海的博客-CSDN博客 正文开始 1…

JS 基础知识

JS 基础知识 JS简介 JavaScript是一种基于对象和事件驱动并具有安全性能的解释型脚本&#xff0c;在Web应用中得到了非常广泛的应用。它不需要编译&#xff0c;而是直接嵌入在HTTP页面中&#xff0c;把静态页面转变成支持用户交互并响应应用的动态页面。在JavaWeb程序中&#x…

网页游戏开发基础——JavaScript基础知识

对于初学编程的朋友来说&#xff0c;这篇文章有点长&#xff0c;而且会有点难懂。但是请不要放弃&#xff0c;我尽量以通俗的语言解释相关的编程概念&#xff0c;这里只讲解编写一个游戏需要的相关编程概念&#xff08;如需要会在后面的文章中随时补充相关概念&#xff09;&…

js基础知识

1、JS的组成 JS由 ECMAscript BOM DOM组成 ECMAscript是JS基础规范、定义了JS基础语法 BOM浏览器对象模型 DOM文档对象模型 2、JS数据类型 基本数据类型&#xff1a;string number boolean undefined null symbol biginit 引用数据类型&#xff1a;object function ar…

Node.js基础知识

目录 1、为什么浏览器和Node.js都可以运行JavaScript 2、浏览器中运行JavaScript和Node.js中运行JavaScript有什么区别 3、为什么在浏览器中JavaScript不能控制系统级别的API 4、Node.js能做什么 5、全局对象-Node.js和浏览器 6、模块系统 7、Node.js是如何实现模块的&…

JavaScript的基础知识

1.JavaScript简介 以下注解可作为拓展材料&#xff1a; 1、脚本语言又被称为扩建的语言&#xff0c;或者动态语言&#xff0c;是一种编程语言&#xff0c;用来控制软件应用程序&#xff0c;脚本通常以文本&#xff08;如ASCII)保存&#xff0c;只在被调用时进行解释或编译。 …

Javascript 基础知识学习

Javascript 基础知识学习 参考自&#xff1a;https://www.w3cschool.cn/javascript/ javascript 简介 JavaScript 是互联网上最流行的脚本语言&#xff0c;这门语言可用于 HTML 和 web&#xff0c;更可广泛用于服务器、PC、笔记本电脑、平板电脑和智能手机等设备。 JavaScri…

JavaScript基础知识总结

一、基本语法&#xff08;数量&#xff0c;数据类型和运算符&#xff09; 1.变量&#xff1a;指的是在数据中心保存数据的容器 变量是计算机内存中存储数据的标识符&#xff0c;根据变量名称可以获取到内存中存储的数据 也就是说&#xff0c;我们向内存中存储了一个数据&…

JS基础知识总结 (一)

一、JS简介 JavaScript是一种运行在客户端的脚本语言&#xff0c;最早是在HTML&#xff08;标准通用标记语言下的一个应用&#xff09;网页上使用&#xff0c;用来给HTML网页增加动态功能。 浏览器就是一种运行JavaScript脚本语言的客户端&#xff0c;JavaScript的解释器被称为…

最新Javascript 基础知识全总结(持续更新)

目录 一,JavaScript 是什么 1, JavaScript 是什么 2, 作用 3, JavaScript的组成 二, JavaScript 书写位置 1,内部 JavaScript 2, 外部 JavaScript 3, 内联 JavaScript 三, JavaScript 的注释 1, 单行注释 2, 多行注释 四, JavaScript的结束符 五, 输入和输出语法 …

JS入门基础知识

一、JS是什么 1、JS概述 JavaScript是一个轻量级的语句&#xff0c;他是单线程的语言&#xff08;一个线程解析&#xff09;。他是一个弱语言&#xff08;他没有固定 的类型划分 你给定的值是什么类型 他就是什么类型&#xff09;他还是一个脚本语言&#xff08;侵入 实现xss攻…

2020年4月中国编程语言排行榜

本文已过时 都7月了&#xff0c;你该看7月的数据去了&#xff1a; 2020年7月中国编程语言排行榜 2020年7月程序员工资统计&#xff0c;平均14357元&#xff0c;又跌了&#xff0c;扎心 编程语言比例 排名编程语言平均工资工资中位数最低工资最高工资人头人头百分比1rust2…

2020年5月中国编程语言排行榜

本文已过时 都7月了&#xff0c;你该看7月的数据去了&#xff1a; 2020年7月中国编程语言排行榜 2020年7月程序员工资统计&#xff0c;平均14357元&#xff0c;又跌了&#xff0c;扎心 编程语言比例 排名编程语言平均工资工资中位数最低工资最高工资人头人头百分比1scala20…

2021年10月世界编程语言排行

2021 年10 月的 TIOBE 指数 10月头条&#xff1a;Python编程语言流行指数排名第一&#xff01; 20多年来&#xff0c;我们第一次有了一个新的领导者&#xff1a;Python编程语言。Java和C的长期霸权已经结束。Python最初是一种简单的脚本语言&#xff0c;作为Perl的替代品&…