一、说明

在实际开发中,为了保护用户信息的安全,都会在网站登录界面上添加一次性验证码,从而限制人们使用软件来暴力猜测密码。在实现用户登录案例中,增加一次性验证码功能。

验证码是4个随机字符,以图片的形式展示给用户。

二、实现步骤

1.修改登录页面login.html

增加验证码输入框和验证码图片

<form name="reg" action="/chapter05/LoginServlet" method="post">     用户名: <input name="username" type="text" /><br />                 密&nbsp;&nbsp;码:<input name="password" type="password" /><br />   验证码:<input type="text" name="check_code">                        <img src="/chapter05/CheckServlet"><br>                          <input type="submit" value="提交" id="bt" />
</form>                                                              

2.创建CheckServlet类

用于产生验证码图片

public class CheckServlet extends HttpServlet{private static int WIDTH = 60; //验证码图片宽度private static int HEIGHT = 20; //验证码图片高度public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{     HttpSession session = request.getSession();response.setContentType("image/jpeg");ServletOutputStream sos = response.getOutputStream();//设置浏览器不要缓存此图片response.setHeader("Pragma","No-cache");response.setHeader("Cache-Control","no-cache");response.setDateHeader("Expires", 0);//创建内存图象并获得其图形上下文BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); Graphics g = image.getGraphics();//产生随机的认证码char [] rands = generateCheckCode();//产生图像drawBackground(g);drawRands(g,rands);//结束图像的绘制过程,完成图像g.dispose();//将图像输出到客户端ByteArrayOutputStream bos = new ByteArrayOutputStream();ImageIO.write(image, "JPEG", bos);byte [] buf = bos.toByteArray();response.setContentLength(buf.length);//下面的语句也可写成:bos.writeTo(sos);sos.write(buf);bos.close();sos.close();//将当前验证码存入到Session中session.setAttribute("check_code",new String(rands));//直接使用下面的代码将有问题,Session对象必须在提交响应前获得//request.getSession().setAttribute("check_code",new String(rands));}//生成一个4字符的验证码private char [] generateCheckCode(){//定义验证码的字符表String chars = "0123456789abcdefghijklmnopqrstuvwxyz";char [] rands = new char[4];for(int i=0; i<4; i++){int rand = (int)(Math.random() * 36);rands[i] = chars.charAt(rand);}return rands;}private void drawRands(Graphics g , char [] rands){g.setColor(Color.BLACK);g.setFont(new Font(null,Font.ITALIC|Font.BOLD,18));//在不同的高度上输出验证码的每个字符        g.drawString("" + rands[0],1,17);g.drawString("" + rands[1],16,15);g.drawString("" + rands[2],31,18);g.drawString("" + rands[3],46,16);System.out.println(rands);}private void drawBackground(Graphics g){//画背景g.setColor(new Color(0xDCDCDC));g.fillRect(0, 0, WIDTH, HEIGHT);//随机产生120个干扰点for(int i=0; i<120; i++){int x = (int)(Math.random() * WIDTH);int y = (int)(Math.random() * HEIGHT);int red = (int)(Math.random() * 255);int green = (int)(Math.random() * 255);int blue = (int)(Math.random() * 255);g.setColor(new Color(red,green,blue));     g.drawOval(x,y,1,0);}}}

3.修改LoginServlet

增加对验证码的判断

/**                                                                                              * 添加了验证码                                                                                        */
public void doGet(HttpServletRequest request, HttpServletResponse response)                      throws ServletException, IOException {                                                   response.setContentType("text/html;charset=utf-8");                                          String username = request.getParameter("username");                                          String password = request.getParameter("password");                                          String checkCode = request.getParameter("check_code");                                       String savedCode = (String) request.getSession().getAttribute("check_code");                 PrintWriter pw = response.getWriter();                                                       if (("itcast").equals(username) && ("123").equals(password) && checkCode.equals(savedCode)) {User user = new User();                                                                  user.setUsername(username);                                                              user.setPassword(password);                                                              request.getSession().setAttribute("user", user);                                         response.sendRedirect("/chapter05/IndexServlet");                                        } else if (checkCode.equals(savedCode)) {                                                    pw.write("用户名或密码错误,登录失败");                                                               } else {                                                                                     pw.write("验证码错误");                                                                       }
}                                                                                                

三、启动Tomcat,测试验证码

http://localhost:8080/chapter05/login.html

如果用户名和密码正确,但不填验证码:

利用Session实现一次性验证码(多学一招)相关推荐

  1. java session验证码_利用session实现一次性验证码

    带有验证码的登录页面 用户名: 密码: 验证码: import java.io.*; import javax.servlet.*; import javax.servlet.http.*; impo ...

  2. 简单的Session案例 —— 一次性验证码

    一次性验证码的主要目的就是为了限制人们利用工具软件来暴力猜测密码,其原理与利用Session防止表单重复提交的原理基本一样,只是将表单标识号变成了验证码的形式,并且要求用户将提示的验证码手工填写进一个 ...

  3. html验证码的原理,滑动验证码的原理并利用 Vue 实现滑动验证码

    做网络爬虫的同学肯定见过各种各样的验证码,比较高级的有滑动.点选等样式,看起来好像挺复杂的,但实际上它们的核心原理还是还是很清晰的,本文章大致说明下这些验证码的原理以及带大家实现一个滑动验证码. 我之 ...

  4. 多学一招总没错吧?MP通用枚举轻松实现存储显示相分离

    狡兔尚且三窟,多学一招总没错吧?

  5. ajas php 验证码_thinkPHP3.2.3利用Ajax前台实现验证码验证,但通过form表单的按钮提交后,验证码一直错误!如何解决?...

    展开全部 我用的方法是判断$_session里的验证码值是否与post提交的验证码值是否相等,经过测试没有问636f707962616964757a686964616f31333363396432题, ...

  6. 【转载】C语言,利用网络短信验证码接口实现手机短信发送

    利用网络短信验证码接口实现手机短信发送 (历史代码,贴出学习) resource.h //resource.h//{{NO_DEPENDENCIES}} // Microsoft Visual C++ ...

  7. php通过session保存用户信息,如何在php中利用session与cookie保存用户的登录信息

    如何在php中利用session与cookie保存用户的登录信息 发布时间:2020-12-18 15:49:56 来源:亿速云 阅读:95 作者:Leah 如何在php中利用session与cook ...

  8. 利用IO流一次性读取文件中的所有内容,利用IO流下载文件

    利用IO流一次性读取文件中的所有内容 读取文件效率最快的方法就是一次全读进来,使用readline()之类的方法,可能需要反复访问文件,而且每次readline()都会调用编码转换,降低了速度,所以, ...

  9. Python 利用百度文字识别验证码、文字、图片并提取图片中文字或数字

    Python 利用百度文字识别验证码.文字.图片并提取图片中文字或数字 Python 利用百度文字识别验证码.文字.图片并提取图片中文字或数字 以下是代码实现, Python 利用百度文字识别验证码. ...

最新文章

  1. Android 最火的快速开发框架XUtils
  2. 网狐棋牌(八) 异步引擎 和 网狐棋牌(九) 服务引擎概览
  3. cf1526 C Potions
  4. Python 并行分布式框架 Celery
  5. Android 8.0 学习(3)---Android 8.0系统的应用图标适配
  6. 转录组分析_肠道菌群:宏转录组测序分析流程解读
  7. Android学习笔记:利用httpclient和AsyncTask 发起网络http post操作
  8. [Ext JS 7]基于NPM的开发
  9. python以读写方式打开文件_python 文件读写with open模式r,r+,w,w+,a,a+的区别
  10. 也谈设计模式,实例票据打印 解析 Decorator
  11. linux 内核模块 定时器,linux内核定时器__backup_timer_hour_struct_定时器_模块__169IT.COM...
  12. lzg_ad:EWF启用常见问题及解决方案
  13. 2019河南对口升学高考试卷计算机专业课,2019河南对口升学高考试卷计算机专业课-9页word资料...
  14. 面向对象C#初级入门精讲(2)C#语言基础-徐照兴-专题视频课程
  15. BEPU物理引擎碰撞系统的架构与设计
  16. ForkJoin框架源码分析(详细)
  17. unity 物体移动到手机点击位置
  18. 云计算中Region、AZ、POD的三角关系
  19. OSPF拓扑图和路由器类型
  20. CAS统一登录认证(1): 搭建 CAS Server

热门文章

  1. 【kafka】Kafka 之 Group 状态变化分析及 Rebalance 过程
  2. 【Elasticsearch】Elasticsearch 通信模块的分析
  3. 【hortonworks/registries】registries curator LeaderLatch: getChildren() failed. rc = -6 Xid 110
  4. 95-241-102-源码-Flink语义-Flink的exectly-once系列之两阶段提交实现分析
  5. Flink读取Kafka报错:KafkaException ByteArrayDeserializer is not an instance Deserializer
  6. java.sql.SQLException: ORA01555: 快照过旧: 回退段号 4 过小
  7. 大数据面试-03-大数据工程师面试题
  8. python redis 集群_python与java中使用redis集群
  9. ef 批量保存 oracle,mybatis-oracle与mysql批量添加
  10. SpringBoot 整合 MyCat 实现读写分离