简单的Session案例 —— 一次性验证码
- 一次性验证码的主要目的就是为了限制人们利用工具软件来暴力猜测密码,其原理与利用Session防止表单重复提交的原理基本一样,只是将表单标识号变成了验证码的形式,并且要求用户将提示的验证码手工填写进一个表单字段中,而不是通过表单的隐藏字段自动回传给服务器。
- 服务器程序接收到表单数据后,首先判断用户是否填写了正确的验证码,只有该验证码与服务器端保存的验证码匹配时,服务器程序才开始正常的表单处理流程。
- 密码猜测工具要逐一尝试每个密码的前题条件是先输入正确的验证码,而验证码是一次性有效的,这样基本上就阻断了密码猜测工具的自动地处理过程。
表单页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${MessageIfo}
<form action="<%=request.getContextPath()%>/checkCodeServlet" method="post">
Username:<input type="text" name="username"/>
<br><br>
验证码:<input type="text" name="checkCode"/>
<br><br>
<img src="<%=request.getContextPath()%>/validateColorServlet">
<br><br>
<input type="submit" value="登录"/>
</form>
</body>
</html>
生成验证码的Servlet
package yang.mybatis.servlet.checkCode; import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random; import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Created by yangshijing on 2017/11/23 0023.
*/
public class ValidateColorServlet extends HttpServlet { public static final String CHECK_CODE_KEY = "CHECK_CODE_KEY"; private static final long serialVersionUID = 1L; //设置验证图片的宽度, 高度, 验证码的个数
private int width = 152;
private int height = 40;
private int codeCount = 4; //验证码字体的高度
private int fontHeight = 4; //验证码中的单个字符基线. 即:验证码中的单个字符位于验证码图形左上角的 (codeX, codeY) 位置处
private int codeX = 0;
private int codeY = 0; //验证码由哪些字符组成
char [] codeSequence = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz23456789".toCharArray(); //初始化验证码图形属性
public void init(){
fontHeight = height - 2;
codeX = width / (codeCount + 2);
codeY = height - 4;
} public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//定义一个类型为 BufferedImage.TYPE_INT_BGR 类型的图像缓存
BufferedImage buffImg = null;
buffImg = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR); //在 buffImg 中创建一个 Graphics2D 图像
Graphics2D graphics = null;
graphics = buffImg.createGraphics(); //设置一个颜色, 使 Graphics2D 对象的后续图形使用这个颜色
graphics.setColor(Color.WHITE); //填充一个指定的矩形: x - 要填充矩形的 x 坐标; y - 要填充矩形的 y 坐标; width - 要填充矩形的宽度; height - 要填充矩形的高度
graphics.fillRect(0, 0, width, height); //创建一个 Font 对象: name - 字体名称; style - Font 的样式常量; size - Font 的点大小
Font font = null;
font = new Font("", Font.BOLD, fontHeight);
//使 Graphics2D 对象的后续图形使用此字体
graphics.setFont(font); graphics.setColor(Color.BLACK); //绘制指定矩形的边框, 绘制出的矩形将比构件宽一个也高一个像素
graphics.drawRect(0, 0, width - 1, height - 1); //随机产生 15 条干扰线, 使图像中的认证码不易被其它程序探测到
Random random = null;
random = new Random();
graphics.setColor(Color.GREEN);
for(int i = 0; i < 15; i++){
int x = random.nextInt(width);
int y = random.nextInt(height);
int x1 = random.nextInt(20);
int y1 = random.nextInt(20);
graphics.drawLine(x, y, x + x1, y + y1);
} //创建 randomCode 对象, 用于保存随机产生的验证码, 以便用户登录后进行验证
StringBuffer randomCode;
randomCode = new StringBuffer(); for(int i = 0; i < codeCount; i++){
//得到随机产生的验证码数字
String strRand = null;
strRand = String.valueOf(codeSequence[random.nextInt(36)]); //把正在产生的随机字符放入到 StringBuffer 中
randomCode.append(strRand); //用随机产生的颜色将验证码绘制到图像中
graphics.setColor(Color.BLUE);
graphics.drawString(strRand, (i + 1)* codeX, codeY);
} //再把存放有所有随机字符的 StringBuffer 对应的字符串放入到 HttpSession 中
request.getSession().setAttribute(CHECK_CODE_KEY, randomCode.toString()); //禁止图像缓存
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0); //将图像输出到输出流中
ServletOutputStream sos = null;
sos = response.getOutputStream();
ImageIO.write(buffImg, "jpeg", sos);
sos.close();
}
}
表单处理Servlet
package yang.mybatis.servlet.checkCode; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException; /**
* Created by yangshijing on 2017/11/23 0023.
*/
public class CheckCodeServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
String check_code_key = (String)session.getAttribute("CHECK_CODE_KEY");
String checkCode = request.getParameter("checkCode");
//不区分大小写
if(check_code_key != null && !check_code_key.trim().equals("")){
check_code_key = check_code_key.toLowerCase();
}
if (checkCode != null && !checkCode.trim().equals("")){
checkCode = checkCode.toLowerCase();
}
//验证码为NULL或者两者不等,重定向到信息提示页面
if(check_code_key == null || checkCode == null && !check_code_key.equals(checkCode)){
request.getSession().setAttribute("MessageIfo","验证不一致");
response.sendRedirect(request.getContextPath()+"/jsp/checkCode/index.jsp");
return;
}
//如果两个验证码一致,处理该表单请求,并移除sesssion域中的属性值
session.removeAttribute("CHECK_CODE_KEY");
response.sendRedirect(request.getContextPath()+"/jsp/token/success.jsp");
}
}
简单的Session案例 —— 一次性验证码的更多相关文章
- 使用session实现一次性验证码
在登录页面和各种页面,会看到有验证码输入,这样做的目的是为了防止密码猜测工具破解密码,保护了用户密码安全,验证码只能使用一次,这样就给密码猜测工具带来了很大的困难,基本上阻断了密码猜测工具的使用. 可 ...
- JavaWeb 使用Session实现一次性验证码
表单 <form action="loginServlet" method="post"> 请输入验证码:<input type=" ...
- session案例之验证码
一.需求分析 其中,一张图片就是一个单独的请求: 一个验证验证码的Servlet,还有一个验证用户名和密码的Servlet,两次都可能有错误信息返回到前端页面,所以前面页面要从request域中获取返 ...
- JAVA实用案例之验证码开发
验证码在很多地方都会遇到,实现的方法和形式也有很多,主要的目的就是为了安全,防止一些恶意的攻击等.说实话那么多年竟然没注意过这东西,原理很简单,贴出来给大家做个参考. 1.简单介绍 一般稍微有些经验的 ...
- Java Web(四) 一次性验证码的代码实现
其实实现代码的逻辑非常简单,真的超级超级简单. 1.在登录页面上login.jsp将验证码图片使用标签<img src="xxx">将绘制验证码图片的url给它 2.在 ...
- web开发(四) 一次性验证码的代码实现
在网上看见一篇不错的文章,写的详细. 以下内容引用那篇博文.转载于<http://www.cnblogs.com/whgk/p/6426072.html>,在此仅供学习参考之用. 其实实现 ...
- Python3+Dlib实现简单人脸识别案例
Python3+Dlib实现简单人脸识别案例 写在前边 很早很早之前,当我还是一个傻了吧唧的专科生的时候,我就听说过人脸识别,听说过算法,听说过人工智能,并且也出生牛犊不怕虎般的学习过TensorFl ...
- Session中短信验证码设置有效时间
Session中短信验证码设置有效时间 package com.mozq.boot.kuayu01.controller; import org.springframework.web.bind.an ...
- 使用Java实现简单的斗地主案例
使用Java实现简单的斗地主案例 案例说明:使用Java实现简单的斗地主洗牌发牌的操作: 具体规则: 共有54张牌,顺序打乱: 三个玩家参与游戏,三人交替摸牌,每人17张牌,最后留三张为底牌(地主牌) ...
随机推荐
- Spring aop 简单示例
简单的记录一下spring aop的一个示例 基于两种配置方式: 基于xml配置 基于注解配置 这个例子是模拟对数据库的更改操作添加事物 其实并没有添加,只是简单的输出了一下记录 首先看下整个例子的目 ...
- Python 函数 -next()
next() next() 返回迭代器的下一个项目. iterator - 可迭代对象. default - 可选,用于设置在没有下一个元素时返回该默认值,如果不设置,又没有下一个元素则会触发 St ...
- FastAdmin 2018-05-26 更新时更新了 SQL 文件 关于 ROW_FORMAT=DYNAMIC 改为 ROW_FORMAT=COMPACT 问题
FastAdmin 2018-05-26 更新时更新了 SQL 文件 关于 ROW_FORMAT=DYNAMIC 改为 ROW_FORMAT=COMPACT 问题 观查到 FastAdmin 在 20 ...
- bzoj 3796 Mushroom追妹纸——后缀数组
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3796 长度一般都是 1e5 ,看这个是 5e4 ,一看就是把两个串接起来做. 自己本来想的是 ...
- React组件性能优化总结
性能优化的思路 影响网页性能最大的因素是浏览器的重排(repaint)和重绘(reflow). React的Virtual DOM就是尽可能地减少浏览器的重排和重绘. 从React渲染过程来看,如何防 ...
- 【转】java接口的性能测试
这周尝试了一把性能测试,之前都是测试网站的性能测试,java接口的性能测试还是头一次,学到了很多,特此分享一下. 主要用到了两个性能测试工具,一个是jmeter,一个是LoadRunner. 使用jm ...
- php对数组中的值进行排序
案例 <?php $a = array('1124','1125','1126'); $s1 = 1124; $s2 = 1125; $ks1 = array_search($s1,$a); $ ...
- linux中内存使用,swap,cache,buffer的含义总结
首先介绍一下linux中内存是如何使用的.当有应用需要读写磁盘数据时,由系统把相关数据从磁盘读取到内存,如果物理内存不够,则把内存中的部分数据导入到磁盘,从而把磁盘的部分空间当作虚拟内存来使用,也称为 ...
- 如何使用Visual Studio2015进行C++项目创建
打开Visual Studio 2015,点击程序左上角的“文件”--“新建”--“项目”. 在弹出窗口选择模板“visual C++”,在新建项目栏里选择“win32控制台应用程序”,直接点击确定. ...
- MongoDB在Java下的增删查改
我们总不能一直使用cmd对数据库操作,数据库总是要在程序中使用的.今天来说一下怎么通过Java调用MongoDB. 学习一下最基本也是最常用的增删查改语句,这是使用数据库的基础. 注意事项: 1.要打 ...