JavaWeb - 验证码

本文涉及的产品
函数计算FC,每月15万CU 3个月
简介: JavaWeb - 验证码
  1. 为什么要学习验证码?
    1、可以防止恶意破解密码、刷票、论坛灌水。
    2、有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试。
    3、实际上用验证码是现在很多网站通行的方式,我们利用比较简易的方式实现了这个功能。
  2. 验证码实现的方式
    1、字母数字混合验证码
importjavax.imageio.ImageIO;
importjavax.servlet.http.HttpServletResponse;
importjava.awt.*;
importjava.awt.font.FontRenderContext;
importjava.awt.geom.Rectangle2D;
importjava.awt.image.BufferedImage;
importjava.util.Random;
/*** 此方法用户产生随机数-字母和数字* @return*/privatestaticcharrandomChar(){
//1:定义验证需要的字母和数字Stringstring="QWERTYUIOPASDFGHJKLZXCVBNM0123456789";
//2:定义随机对象Randomrandom=newRandom();
returnstring.charAt(random.nextInt(string.length()));
}
/*** 字母数字混合验证码* @param response* @return*/publicstaticStringdrawImage(HttpServletResponseresponse){
//1:定义以字符串的拼接的StringBuilderStringBuilderbuilder=newStringBuilder();
//准备产生4个字符串的随机数for(inti=0;i<4;i++){
builder.append(randomChar());
    }
Stringcode=builder.toString();
//2:定义图片的宽度和高度intwidth=70;
intheight=25;
//简历bufferedImage对象,制定图片的长度和宽度以及色彩BufferedImagebi=newBufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR);
//3:获取到 Graphics2D 绘制对象,开始绘制验证码Graphics2Dg=bi.createGraphics();
//4:设置文字的字体和大小Fontfont=newFont("微软雅黑",Font.PLAIN,20);
//设置字体的颜色Colorcolor=newColor(0,0,0);
//设置字体g.setFont(font);
//设置颜色g.setColor(color);
//设置背景g.setBackground(newColor(226,226,240));
//开始绘制对象g.clearRect(0,0,width,height);
//绘制形状,获取矩形对象FontRenderContextcontext=g.getFontRenderContext();
Rectangle2Dbounds=font.getStringBounds(code,context);
//计算文件的坐标和间距doublex= (width-bounds.getWidth())/2;
doubley= (height-bounds.getHeight())/2;
doubleascent=bounds.getY();
doublebaseY=y-ascent;
g.drawString(code,(int)x,(int)baseY);
//结束绘制g.dispose();
try {
ImageIO.write(bi,"jpg",response.getOutputStream());
//刷新响应流response.flushBuffer();
    }catch(Exceptionex){
ex.printStackTrace();
    }
returncode;
}
// code.jsp<%@pageimport="com.imooc.code.CaptcahCode"%><%@pagecontentType="text/html;charset=UTF-8"language="java"%><%// 清空浏览器缓存,目的是为了清空浏览器的缓存,因为浏览器会对网站的资源文件和图像进行记忆存储,// 如果被浏览器加载过的图片就记忆起来,记忆以后,// 文件就不会和服务器在交互,如果我们验证不清空的话可能会造成一个问题就是:验证刷新以后没有效果。response.setHeader("pragma","no-cache");
response.setHeader("cache-control","no-cache");
response.setHeader("expires","0");
//2:调用编写的生成验证码的工具Stringcode=CaptcahCode.drawImage(response);
session.setAttribute("code",code);
//3:如何解决getOutputStream异常问题out.clear();
out=pageContext.pushBody();
%>
// index.jsp<%@pagelanguage="java"import="java.util.*"pageEncoding="UTF-8"%><!DOCTYPEHTML><html><head><title>java验证码</title><metahttp-equiv="pragma"content="no-cache"><metahttp-equiv="cache-control"content="no-cache"><metahttp-equiv="expires"content="0"></head><body><imgsrc="code.jsp"alt=""id="code"><ahref="javascript:void(0);"onclick="changeCode()">看不清?点我</a><script>functionchangeCode() {
document.getElementById("code").src="code.jsp?d="+newDate().getTime();
         }
</script></body></html>

2、算术验证码

image.png

image.png

importjavax.imageio.ImageIO;
importjavax.servlet.http.HttpServletResponse;
importjava.awt.*;
importjava.awt.font.FontRenderContext;
importjava.awt.geom.Rectangle2D;
importjava.awt.image.BufferedImage;
importjava.util.Random;
/*** 范围随机颜色* @param fc* @param bc* @return*/publicstaticColorgetRandomColor(intfc,intbc){
//利用随机数Randomrandom=newRandom();
//随机颜色,了解颜色-Color(red,green,blue).rgb三元色 0-255if(fc>255)fc=255;
if(bc>255)bc=255;
intr=fc+random.nextInt(bc-fc);
intg=fc+random.nextInt(bc-fc);
intb=fc+random.nextInt(bc-fc);
returnnewColor(r,g,b);
}
/*** 算术表达式验证码** 1:干扰线的产生* 2: 范围随机颜色,随机数** @param response* @return*/publicstaticStringdrawImageVerificate(HttpServletResponseresponse){
//定义验证码的宽度和高度intwidth=100,height=30;
//在内存中创建图片BufferedImageimage=newBufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
//创建图片的上下文Graphics2Dg=image.createGraphics();
//产生随机对象,此随机对象主要用于算术表达式的数字Randomrandom=newRandom();
//设置背景g.setColor(getRandomColor(240,250));
//设置字体g.setFont(newFont("微软雅黑", Font.PLAIN,22));
//开始绘制g.fillRect(0,0,width,height);
//干扰线的绘制,绘制线条到图片中g.setColor(getRandomColor(180,230));
for(inti=0;i<10;i++){
intx=random.nextInt(width);
inty=random.nextInt(height);
intx1=random.nextInt(60);
inty1=random.nextInt(60);
g.drawLine(x,y,x1,y1);
    }
//开始进行对算术验证码表达式的拼接intnum1= (int)(Math.random()*10+1);
intnum2= (int)(Math.random()*10+1);
intfuhao=random.nextInt(3);//产生一个[0,2]之间的随机整数//记录符号Stringfuhaostr=null;
intresult=0;
switch (fuhao){
case0 : fuhaostr="+";result=num1+num2;break;
case1: fuhaostr="-";result=num1-num2;break;
case2 : fuhaostr="*";result=num1*num2;break;
//case 3 : fuhaostr = "/";result = num1 / num2;break;    }
//拼接算术表达式,用户图片显示。Stringcalc=num1+" "+fuhaostr+" "+num2+" = ?";
//设置随机颜色g.setColor(newColor(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));
//绘制表达式g.drawString(calc,5,25);
//结束绘制g.dispose();
try {
//输出图片到页面ImageIO.write(image,"JPEG",response.getOutputStream());
returnString.valueOf(result);
    }catch (Exceptionex){
ex.printStackTrace();
returnnull;
    }
}
// code.jsp<%@pageimport="com.imooc.code.CaptcahCode"%><%@pagecontentType="text/html;charset=UTF-8"language="java"%><%// 清空浏览器缓存,目的是为了清空浏览器的缓存,因为浏览器会对网站的资源文件和图像进行记忆存储,// 如果被浏览器加载过的图片就记忆起来,记忆以后,// 文件就不会和服务器在交互,如果我们验证不清空的话可能会造成一个问题就是:验证刷新以后没有效果。response.setHeader("pragma","no-cache");
response.setHeader("cache-control","no-cache");
response.setHeader("expires","0");
//2:调用编写的生成验证码的工具Stringcode=CaptcahCode.drawImageVerificate(response);
session.setAttribute("code",code);
//3:如何解决getOutputStream异常问题out.clear();
out=pageContext.pushBody();
%>
// index.jsp<%@pagelanguage="java"import="java.util.*"pageEncoding="UTF-8"%><!DOCTYPEHTML><html><head><title>java验证码</title><metahttp-equiv="pragma"content="no-cache"><metahttp-equiv="cache-control"content="no-cache"><metahttp-equiv="expires"content="0"></head><body><imgsrc="code.jsp"alt=""id="code"><ahref="javascript:void(0);"onclick="changeCode()">看不清?点我</a><script>functionchangeCode() {
document.getElementById("code").src="code.jsp?d="+newDate().getTime();
         }
</script></body></html>

3、kcaptcha

// index.jsp<%@pagecontentType="text/html;charset=UTF-8"language="java"%><html><head><title>关于验证码框架之---Kaptcha</title></head><body><formaction="submit.action"><inputtype="text"name="kaptcha"value=""/><imgsrc="http://localhost:8080/imooccode/kaptcha.jpg"/></form></body></html>
// web.xml<?xmlversion="1.0"encoding="UTF-8"?><web-appxmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"version="3.1"><!--关于kaptcha验证码的配置--><!--<servlet><servlet-name>Kaptcha</servlet-name><servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class></servlet><servlet-mapping><servlet-name>Kaptcha</servlet-name><url-pattern>/kaptcha.jpg</url-pattern></servlet-mapping>--><servlet><servlet-name>Kaptcha</servlet-name><servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class><init-param><param-name>kaptcha.border</param-name><param-value>no</param-value></init-param><init-param><param-name>kaptcha.image.width</param-name><param-value>100</param-value></init-param><init-param><param-name>kaptcha.image.height</param-name><param-value>40</param-value></init-param><init-param><param-name>kaptcha.textproducer.font.size</param-name><param-value>28</param-value></init-param><init-param><param-name>kaptcha.textproducer.char.string</param-name><param-value>qwertyuiopasdfghjklzxcvbnm123456789</param-value></init-param><init-param><param-name>kaptcha.textproducer.char.length</param-name><param-value>4</param-value></init-param><init-param><param-name>kaptcha.noise.impl</param-name><param-value>com.google.code.kaptcha.impl.DefaultNoise</param-value></init-param><init-param><param-name>kaptcha.obscurificator.impl</param-name><param-value>com.google.code.kaptcha.impl.FishEyeGimpy</param-value></init-param><init-param><!--session.setAttribute("kcode",生成好的验证码)--><param-name>kaptcha.session.key</param-name><param-value>kcode</param-value></init-param></servlet><servlet-mapping><servlet-name>Kaptcha</servlet-name><url-pattern>/kaptcha.jpg</url-pattern></servlet-mapping><servlet><servlet-name>LoginServlet</servlet-name><servlet-class>com.imooc.code.LoginServlet</servlet-class></servlet><servlet-mapping><servlet-name>LoginServlet</servlet-name><url-pattern>/login</url-pattern></servlet-mapping>--></web-app>
// 配置详情.txtKaptcha是一个基于SimpleCaptcha的验证码开源项目。官网地址:http://code.google.com/p/kaptcha/kaptcha的使用比较方便,只需添加jar包依赖之后简单地配置就可以使用了。kaptcha所有配置都可以通过web.xml来完成,如果你的项目中使用了SpringMVC,那么则有另外的一种方式来实现。一、简单的jsp-servlet项目1.添加jar包依赖如果你使用maven来统一管理jar包,则在工程的pom.xml中添加dependencyXml代码收藏代码<!--kaptcha--><dependency><groupId>com.google.code.kaptcha</groupId><artifactId>kaptcha</artifactId><version>2.3.2</version></dependency>如果是非maven管理的项目,则直接在官网下载kaptcha的jar包,然后添加到项目lib库中,下载地址:http://code.google.com/p/kaptcha/downloads/list2.配置web.xml上面说了,kaptcha都是在web.xml中配置,我们必须在web.xml中配置kaptcha的servlet,具体如下:Xml代码收藏代码<servlet><servlet-name>Kaptcha</servlet-name><servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class></servlet><servlet-mapping><servlet-name>Kaptcha</servlet-name><url-pattern>/kaptcha.jpg</url-pattern></servlet-mapping>其中servlet的url-pattern可以自定义。kaptcha所有的参数都有默认的配置,如果我们不显示配置的话,会采取默认的配置。如果要显示配置kaptcha,在配置kaptcha对应的Servlet时,在init-param增加响应的参数配置即可。示例如下:Xml代码收藏代码<servlet><servlet-name>Kaptcha</servlet-name><servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class><init-param><param-name>kaptcha.image.width</param-name><param-value>200</param-value><description>Widthinpixelsofthekaptchaimage.</description></init-param><init-param><param-name>kaptcha.image.height</param-name><param-value>50</param-value><description>Heightinpixelsofthekaptchaimage.</description></init-param><init-param><param-name>kaptcha.textproducer.char.length</param-name><param-value>4</param-value><description>Thenumberofcharacterstodisplay.</description></init-param><init-param><param-name>kaptcha.noise.impl</param-name><param-value>com.google.code.kaptcha.impl.NoNoise</param-value><description>Thenoiseproducer.</description></init-param></servlet>具体的配置参数参见:http://code.google.com/p/kaptcha/wiki/ConfigParametersConstant描述默认值kaptcha.border图片边框,合法值:yes , noyeskaptcha.border.color边框颜色,合法值:r,g,b (andoptionalalpha) 或者white,black,blue.   blackkaptcha.border.thickness边框厚度,合法值:>01kaptcha.image.width图片宽200kaptcha.image.height图片高50kaptcha.producer.impl图片实现类com.google.code.kaptcha.impl.DefaultKaptchakaptcha.textproducer.impl文本实现类com.google.code.kaptcha.text.impl.DefaultTextCreatorkaptcha.textproducer.char.string文本集合,验证码值从此集合中获取abcde2345678gfynmnpwxkaptcha.textproducer.char.length验证码长度5kaptcha.textproducer.font.names字体Arial, Courierkaptcha.textproducer.font.size字体大小40pxkaptcha.textproducer.font.color字体颜色,合法值:r,g,b或者white,black,blue.   blackkaptcha.textproducer.char.space文字间隔2kaptcha.noise.impl干扰实现类com.google.code.kaptcha.impl.DefaultNoisekaptcha.noise.color干扰颜色,合法值:r,g,b或者white,black,blue.    blackkaptcha.obscurificator.impl图片样式:水纹com.google.code.kaptcha.impl.WaterRipple鱼眼com.google.code.kaptcha.impl.FishEyeGimpy阴影com.google.code.kaptcha.impl.ShadowGimpycom.google.code.kaptcha.impl.WaterRipplekaptcha.background.impl背景实现类com.google.code.kaptcha.impl.DefaultBackgroundkaptcha.background.clear.from背景颜色渐变,开始颜色lightgreykaptcha.background.clear.to背景颜色渐变,结束颜色whitekaptcha.word.impl文字渲染器com.google.code.kaptcha.text.impl.DefaultWordRendererkaptcha.session.keysessionkeyKAPTCHA_SESSION_KEYkaptcha.session.datesessiondateKAPTCHA_SESSION_DATE3.页面调用Html代码收藏代码<formaction="submit.action"><inputtype="text"name="kaptcha"value=""/><imgsrc="kaptcha.jpg"/></form>4.在submit的action方法中进行验证码校验Java代码收藏代码//从session中取出servlet生成的验证码text值StringkaptchaExpected= (String)request.getSession().getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
//获取用户页面输入的验证码StringkaptchaReceived=request.getParameter("kaptcha");
//校验验证码是否正确if (kaptchaReceived==null||!kaptchaReceived.equalsIgnoreCase(kaptchaExpected)){
setError("kaptcha", "Invalid validation code.");
}
注:确保JDK设置了-Djava.awt.headless=true5.实现页面验证码刷新Html代码收藏代码<imgsrc="kaptcha.jpg"width="200"id="kaptchaImage"title="看不清,点击换一张"/><scripttype="text/javascript">$(function() {
$('#kaptchaImage').click(function() {$(this).attr('src','kaptcha.jpg?'+Math.floor(Math.random() *100));});
    });
</script><br/><small>看不清,点击换一张</small>

4、jcaptcha

  1. 了解验证码功能的实现与原理

image.pngimage.pngimage.pngimage.png

4.kcaptcha 应用版(在2的kcaptcha的基础上

image.png

// test.jsp<%--CreatedbyIntelliJIDEA.
User: AdministratorDate: 2017/9/8Time: 21:10TochangethistemplateuseFile|Settings|FileTemplates.
--%><%@pagecontentType="text/html;charset=UTF-8"language="java"%><html><head><title>登录</title><style>#code{height:30px;}</style></head><body><formaction="submit.action"><p><inputtype="text"name="kaptcha"id="code"value=""maxlength="4"placeholder="请输入验证码"/><imgsrc="http://localhost:8080/imooccode/kaptcha.jpg"id="changecode"/></p><p><inputtype="button"id="login"value="登录"></p><divid="result"></div></form><scriptsrc="js/jquery-1.12.4.min.js"type="text/javascript"></script><script>$(function(){
$("#changecode").on("click",function(){
$(this).attr("src","http://localhost:8080/imooccode/kaptcha.jpg?d="+newDate().getTime());
        });
//给登录按钮绑定点击事件$("#login").on("click",function(){
//获取用户输入的验证码varcode=$("#code").val();
//alert(code);varparams= {"code":code};
$.post("http://localhost:8080/imooccode/login",params,function(data){
//                if(data=="fail"){//                     alert("验证码输入有误!");//                }if(data=="success"){
$("#result").html("验证码输入正确");
                }else{
$("#result").html("验证码输入有误,请重新输入...");
$("#code").val("").focus();
                }
            });
        });
    })
</script></body></html>
packagecom.imooc.code;
importcom.google.code.kaptcha.Constants;
importjavax.servlet.ServletException;
importjavax.servlet.annotation.WebServlet;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importjava.io.IOException;
importjava.io.PrintWriter;
publicclassLoginServletextendsHttpServlet {
publicvoiddoPost(HttpServletRequestrequest, HttpServletResponseresponse) throwsServletException, IOException {
//设置编码request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
//获取浏览器输出流对象PrintWriterout=response.getWriter();
//获取用户传递过来的验证码Stringcode=request.getParameter("code");
//获取验证码框架产生的验证码(会话中存储的验证码)StringsessionCode= (String)request.getSession().getAttribute("kcode");
if(code!=null&sessionCode!=null) {
//如果用户输入的验证码和产生在服务器端的验证码一致,那么就告诉用户输入正确if (code.equalsIgnoreCase(sessionCode)) {
//登录逻辑、注册逻辑等相关的业务操作out.print("success");
            } else {
out.print("fail");
            }
        }
out.flush();
out.close();
    }
publicvoiddoGet(HttpServletRequestrequest, HttpServletResponseresponse) throwsServletException, IOException {
this.doPost(request,response);
    }
}

5.待更新...

相关实践学习
【文生图】一键部署Stable Diffusion基于函数计算
本实验教你如何在函数计算FC上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。函数计算提供一定的免费额度供用户使用。本实验答疑钉钉群:29290019867
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
目录
相关文章
|
26天前
|
Java Maven Spring
Java Web 应用中,资源文件的位置和加载方式
在Java Web应用中,资源文件如配置文件、静态文件等通常放置在特定目录下,如WEB-INF或classes。通过类加载器或Servlet上下文路径可实现资源的加载与访问。正确管理资源位置与加载方式对应用的稳定性和可维护性至关重要。
|
29天前
|
存储 安全 搜索推荐
理解Session和Cookie:Java Web开发中的用户状态管理
理解Session和Cookie:Java Web开发中的用户状态管理
50 4
|
3月前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
452 37
|
28天前
|
Java 持续交付 项目管理
使用Maven进行项目管理:提高Java Web开发的效率
Maven 是一款强大的项目管理和构建自动化工具,广泛应用于Java社区。它通过依赖管理、构建生命周期管理、插件机制和多模块项目支持等功能,简化了项目的构建过程,提高了开发效率。本文将介绍Maven的核心功能及其在Java Web开发中的应用。
54 0
|
2月前
|
前端开发 Java 应用服务中间件
Javaweb学习
【10月更文挑战第1天】Javaweb学习
33 2
|
2月前
|
安全 Java Android开发
JavaWeb解压缩漏洞之ZipSlip与Zip炸弹
JavaWeb解压缩漏洞之ZipSlip与Zip炸弹
62 5
WK
|
1月前
|
安全 Java 编译器
C++和Java哪个更适合开发web网站
在Web开发领域,C++和Java各具优势。C++以其高性能、低级控制和跨平台性著称,适用于需要高吞吐量和低延迟的场景,如实时交易系统和在线游戏服务器。Java则凭借其跨平台性、丰富的生态系统和强大的安全性,广泛应用于企业级Web开发,如企业管理系统和电子商务平台。选择时需根据项目需求和技术储备综合考虑。
WK
62 0
|
2月前
|
Java
Java 登录输入的验证码
Java 登录输入的验证码
31 1
|
2月前
|
前端开发 Java API
JAVA Web 服务及底层框架原理
【10月更文挑战第1天】Java Web 服务是基于 Java 编程语言用于开发分布式网络应用程序的一种技术。它通常运行在 Web 服务器上,并通过 HTTP 协议与客户端进行通信。
29 1
|
3月前
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)