问题
保存登录信息,保护某些资源只有在登录验证之后才能访问.
方案
登录信息提交后进行验证,验证通过则将用户信息保存在session中,验证失败则转发回登录页面。对于需要保护的资源,添加从session中获取绑定值的功能,以判断是否能够成功获取绑定的用户信息为判断依据,获取到则代表已验证,则允许访问,获取不到绑定在session中的用户信息,代码验证没有通过,则拒绝访问该资源,而将请求重定向到登陆页面。
步骤
step1 :新建login.jsp页面
<%@ page contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Login</title>
<!--鼠标移入图片,变成手的形状 -->
<style type="text/css">
.s1{
cursor:pointer;
}
</style>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<h2>登录</h2>
<form action="login.do" method="post">
用户名:<input name="uname"/><br><br>
密 码:<input name="pwd" type="password"/><br><br>
验证码: <input name="vcode"/>
<img src="code" onclick="this.src='code?'+Math.random();"
class="s1" title="点击更换"><br><br>
<input type="submit" value="登录"/>
</form>
</body>
</html>
界面如下:
step2 新建ActionServlet类
package web;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class ActionServlet extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//保证正确读取Post提交来的中文
request.setCharacterEncoding("UTF-8");
//保证正确输出中文
response.setContentType("text/html;charset=UTF-8");
//获取uri,并截取action动作
String uri=request.getRequestURI();
String action=uri.substring(uri.lastIndexOf("/")+1,
uri.lastIndexOf("."));
//获取session
//HttpSession session=request.getSession();
//System.out.println(session.getId());
//设定session超时时间为10秒
//session.setMaxInactiveInterval(10);
//判断动作是否为登录
if(action.equals("login")){
String name=request.getParameter("uname");
String pwd=request.getParameter("pwd");
String number=request.getParameter("vcode");
HttpSession session=request.getSession();
//要求大小写一致
String code = (String)session.getAttribute("code").toString();
if(number.equals(code)&&name.equals("111")&&pwd.equals("111")){
//绑定数据
session.setAttribute("uname", name);
//重定向到首页
//response.sendRedirect("index.jsp");
//使用URL重写的方法,改写原本的访问地址
response.sendRedirect(
response.encodeRedirectURL("index.jsp"));
}else{
//登录失败
request.setAttribute("msg", "用户名或密码错误");
request.getRequestDispatcher("login.jsp")
.forward(request, response);
}
}else if(action.equals("logout")){
HttpSession session=request.getSession();
//session失效
session.invalidate();
response.sendRedirect("login.jsp");
}
PrintWriter out = response.getWriter();
out.close();
}
}
step3. 新建 ValidateCode.java
生成验证码
package web;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class ValidateCode extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//0.创建空白图片
BufferedImage image=new BufferedImage(100,30,BufferedImage.TYPE_INT_RGB);
//1.获取图片画笔
Graphics g = image.getGraphics();
Random r=new Random();
//2.设置画笔颜色(Random类中的nextInt(n)返回一个大于等于0,小于n的随机数)
g.setColor(new Color(r.nextInt(255),r.nextInt(255), r.nextInt(255)));
//3.绘制矩形的背景
g.fillRect(0, 0, 100, 30);
//4.调用自定义的方法,获取长度为5的字母数字组合的字符串
String number=getNumber(5);
HttpSession session=request.getSession();
session.setAttribute("code", number);
g.setColor(new Color(0,0,0));
g.setFont(new Font(null,Font.BOLD,24));
//5.设置颜色字体后,绘制字符串(x/y,最左边字符所处的位置)
g.drawString(number, 8, 24);
//6.绘制8条干扰线(alpha表示透明度)
for(int i=0;i<8;i++){
g.setColor(new Color(r.nextInt(255),r.nextInt(255), r.nextInt(255),r.nextInt(255)));
g.drawLine(r.nextInt(100), r.nextInt(30), r.nextInt(100), r.nextInt(30));
}
response.setContentType("image/jpeg");
OutputStream ops = response.getOutputStream();
ImageIO.write(image, "jpeg", ops);
ops.close();
}
//自定义方法,获取长度为5的字母数字组合的字符串
private String getNumber(int size){
String str="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
String number="";
Random r=new Random();
for(int i=0;i<size;i++){
number+=str.charAt(r.nextInt(str.length()));
}
return number;
}
}
step4. 配置web.xml
<servlet>
<servlet-name>ActionServlet</servlet-name>
<servlet-class>web.ActionServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>ValidateCode</servlet-name>
<servlet-class>web.ValidateCode</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ActionServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ValidateCode</servlet-name>
<url-pattern>/code</url-pattern>
</servlet-mapping>
step4. 新建index.jsp
登陆成功时,进入的界面
<%@ page contentType="text/html;charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Login successed</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
<%
//session验证
Object uname=session.getAttribute("uname");
if(uname==null){
response.sendRedirect("login.jsp");
return;
}
%>
</head>
<body>
<h3>首页</h3>欢迎你:<%=uname.toString()%><br><br>
<a href="logout.do">退出</a>
</body>
</html>
成功登陆后,进入的页面
对于上面项目中用到的代码,下面做一个只是梳理。
1、如何删除session对象
立即删除session对象;
session.invalidate();
2、session验证
用户访问需要保护的资源时,可以使用session验证的方式来保证其安全性,比如要求登陆后才能访问的资源
实现session验证,遵循以下步骤
- 使用session.setAttribute()先绑定数据
- 使用session.getAttribute()方式来读取绑定值,如果没有,则跳转回登录页面
3、什么是session超时
- Web服务器会将空闲时间过长的session对象删除掉,以节省服务器内存空间资源
- Web服务器缺省的超时时间限制:一般是30分钟
4、修改session的缺省时间限制
编程方式:
void session.setMaxInactiveInterval(int seconds);
修改web.xml的方式:
<session-config>
<session-timeout>30</session-timeout>
</session-config>
5、session的优缺点
优点
- 安全(将状态保存在服务器端)
- session能够保存的数据类型更丰富,Cookie只能保存字符串
- session能够保存更多的数据,Cookie大约保存4k
缺点
session将状态保存在服务器端,占用服务器的内存,如果用户量过大,会严重影响服务器的性能
本文介绍了如何利用session和验证码实现登录验证。在登录过程中,验证通过后将用户信息存入session,对于受保护资源,检查session中的用户信息以决定访问权限。详细步骤包括验证码生成、session操作、session超时及限制的设置,并讨论了session的优缺点。
1106

被折叠的 条评论
为什么被折叠?



