一、会话
1.定义:
用户打开浏览器—使用浏览器—到关闭的整个过程。
2.会话跟踪:
是web程序中常用的技术,用来跟踪用户的整个会话,常用的会话跟踪技术是Cookie与Session 。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。
二、Cookie机制
一个用户的所有请求操作都应该属于同一个会话。
1.web应用程序:
是使用HTTP协议传输数据。HTTP协议是无状态的协议,一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接,这就是意味着服务器无法从连接上跟踪会话
2.cookie工作原理:
给客户端们办法一个通行证,每人一个,无论谁访问都必须携带自己通行证,这样服务器就能从通行证上确认客户身份了
(1)浏览器端第一次发送请求到服务器端
(2)服务器端创建Cookie,该Cookie中包含用户的信息,然后将该Cookie发送到浏览器端
(3)浏览器端再次访问服务器端时会携带服务器端创建的Cookie
(4)服务器端通过Cookie中携带的数据区分不同的用户
3.实操
- 给cookie一个名字, Cookie cookie=new Cookie(“lastLoginTime”,System.currentTimeMillis()+“”);
public class ServletContext06 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //服务器告诉你,你第一次来把时间封装成一个信件,下次带着信件访问服务器就知道是你来了 //解决文中乱码 req.setCharacterEncoding("utf-16"); resp.setCharacterEncoding("utf-16"); //创建一个输出流对象 PrintWriter out=resp.getWriter(); //Cookie是服务器从客户端获取到的 Cookie[] cookies=req.getCookies();//可能获取到多个Cookie //判断Cookie是否存在 if (cookies!=null){ out.write("你上一次访问的时间是:"); for (int i=0;i<cookies.length;i++){ Cookie cookie=cookies[i]; //判断cookie的名字是否是lastLoginTime,为了找到指定的cookie if (cookie.getName().equals("lastLoginTime")){ //获取cookie的值 long lastLoginTime=Long.parseLong(cookie.getValue()); Date date=new Date(lastLoginTime); out.write(date.toLocaleString()); } } }else{ out.write("这是你第一次访问本网站"); } //服务器给客户端响应一个新cookie,名字叫做lastLoginTime Cookie cookie=new Cookie("lastLoginTime",System.currentTimeMillis()+""); resp.addCookie(cookie); } }
- 设置cookie有效期,浏览器关掉也还有效
//cookie有效期为1天 cookie.setMaxAge(24*60*60);
4.一个浏览器中cookie的上限
- 一个cookie只能保存一个信息
- 一个web站点可以给浏览器发送多个cookie,最多存放20个
- cookie大小限制4kb
- 一个浏览器上限有300个cookie
5.删除cookie
- 不设置有效期,关闭浏览器自动失效
- 设置有效期时间为0
三、session机制
Session域就是另一种会话技术,也叫做服务器端技术。Session的底层也是基于Cookie的,只不过有自己的改变。
- 服务器会给每一个用户(浏览器)创建一个session对象
- 一个session独占一个浏览器,只要浏览器没关,session就存在
- 用户登录后,整个网站都可以访问——》能保存用户信息,保存购物车信息
1.session工作原理
(1)浏览器端第一次发送请求到服务器端,服务器端创建一个Session,同时会创建一个特殊的Cookie(name为jessionID(好像是cookieID一样的唯一标识的东西)的固定值,value为session对象的ID),然后将该Cookie发送至浏览器端
(2)浏览器端发送第N(N>1)次请求到服务器端,浏览器端访问服务器端时就会携带该name为jessionID的Cookie对象
(3)服务器端根据name为jessionID的Cookie的value(sessionID),去查询Session对象,从而区分不同用户。
name为jessionID的Cookie不存在(关闭或更换浏览器),返回1中重新去创建Session与特殊的Cookie
name为jessionID的Cookie存在,根据value中的SessionId去寻找session对象。
value为SessionId不存在(Session对象默认存活30分钟),返回1中重新去创建Session与特殊的Cookie
value为SessionId存在,返回session对象
Session的工作原理图
2.实操
- 创建一个session:session创建的时候同时创建了一个JESSIONID为键、以sessionID为值的cookie
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //解决文中乱码 req.setCharacterEncoding("utf-16"); resp.setCharacterEncoding("utf-16"); resp.setContentType("utf-16"); //得到session HttpSession session=req.getSession(); //给session存东西 session.setAttribute("name","manman"); //获取sessionID String sessionId=session.getId(); //判断session是否新建 if (session.isNew()){ resp.getWriter().write("session创建成功。ID:"+sessionId); }else { resp.getWriter().write("session已经在服务器存在。ID:"+sessionId); } //session创建的时候做了什么事 Cookie cookie=new Cookie("JESSIONID",sessionId); resp.addCookie(cookie); }
- session中可以保存任何东西,并且是所有网页共享的
//网页1——保存一个对象 //得到session HttpSession session=req.getSession(); //给session存东西 session.setAttribute("name",new GetServlet("manamnzi",1)); //网页2——读取对象 HttpSession session=req.getSession(); GetServlet name=(GetServlet)session.getAttribute("name"); System.out.println(name.toString());
- 注销session,一旦注销,再生成就是新的sessionID
//手动注销 session.removeAttrbute("name"); session.invalidate(); //设置session默认的失效时间——在web.xml中 <session-config> <!--15分钟后自动失效,以分钟为单位--> <session-timeout>15</session-timeout> </session-config>
四、cookie和session的区别
1.安全性对比
session
简单的说,当你登陆一个网站的时候,如果web服务器端使用的是session,那么所有的数据都保存在服务器上,客户端每次请求服务器的时候会发送当前会话sessionid,服务器根据当前sessionid判断相应的用户数据标志,以确定用户是否登陆或具有某种权限。由于数据是存储在服务器上面,所以你不能伪造。
cookie
sessionid是服务器和客户端连接时候随机分配的,如果浏览器使用的是cookie,那么所有数据都保存在浏览器端,比如你登陆以后,服务器设置了cookie用户名,那么当你再次请求服务器的时候,浏览器会将用户名一块发送给服务器,这些变量有一定的特殊标记。服务器会解释为cookie变量,所以只要不关闭浏览器,那么cookie变量一直是有效的,所以能够保证长时间不掉线。
如果你能够截获某个用户的cookie变量,然后伪造一个数据包发送过去,那么服务器还是 认为你是合法的。所以,使用cookie被攻击的可能性比较大。
如果cookie设置了有效值,那么cookie会保存到客户端的硬盘上,下次在访问网站的时候,浏览器先检查有没有cookie,如果有的话,读取cookie,然后发送给服务器。
所以你在机器上面保存了某个论坛cookie,有效期是一年,如果有人入侵你的机器,将你的cookie拷走,放在他机器下面,那么他登陆该网站的时候就是用你的身份登陆的。当然,伪造的时候需要注意,直接copy cookie文件到 cookie目录,浏览器是不认的,他有一个index.dat文件,存储了 cookie文件的建立时间,以及是否有修改,所以你必须先要有该网站的 cookie文件,并且要从保证时间上骗过浏览器
两个都可以用来存私密的东西,session过期与否,取决于服务器的设定。cookie过期与否,可以在cookie生成的时候设置进去。
2.区别对比
cookie数据存放在客户的浏览器上,session数据放在服务器上
cooike不是很安全,别人可以分析存放在本地的cooike并进行cooike欺骗,考虑到安全应当使用session
session会在一定时间内保存在服务器上,当访问增多,会比较占用你的服务器性能,考虑减轻服务器性能方面应该使用cooike
单个cooike保存的数据不能超过4k,很多浏览器都限制一个站点最多保存20个cooike
将登陆信息等重要信息存放在session
其他信息如果需要保留可以存在cooike中
五、Request域、ServletContext域、pageContext域、Cookie域、Session域的区别是什么?
用在网上购买东西这个案例来剖析这个问题。
1.request域:表示的是一次请求范围内。
如果说,我要去购买一件上衣向服务器发送一个购买请求,它返回给我一个购买成功的响应;当我再去购买一个裤子的时候就相当于又一个请求,那么这时候用转发的话当然就不行了,如果用重定向的话可以解决这个问题,只不过比较麻烦。然后把里面所购买的上衣的数据从request域拿出来和第二个请求拼接在一起在存入request域中。
但是当我要去结算的,就是在另一个Servlet中,这个时候我的request域中的数据就会全部丢失。具体如下图所示:
2.ServletContext域和pageContext域:
这两个域在我看来没有本质上的区别,可以理解为服务器端的共享空间。只不过说,ServletContext域表示的是整个web服务,而pageContext域表示的是一次请求。
如果说,我要购买一件上衣,向服务器发送一个请求,服务器返回给我一个购买成功的请求 ,同样的再去购买一条裤子也是一样的。看来一切都是正常的,结算也可以去结算界面结算我的总金额。
但是,我要说的是,因为这是一个购物界面,所以就不会只是你一个用户。因为这是一个服务器端的共享空间,所以当别人也去购买东西添加购物车后,你去结算的时候就包括自己和别人共同的东西。具体如下图所示:
3.cookie域
同样去买一件上衣,这个时候就会把上衣这个对象存入的开辟的Cookie空间中, Cookie空间为此对象绑定一个唯一的标识然后以响应头方式返回给客户端,当再去购买裤子的时候会带着这个唯一标识以请求头的方式存入到Cookie空间中,同时为它绑定唯一的标识。因为Cookie域保存在自己浏览器内部,与别人互不干扰,但因为是客户端技术,所以安全性不高。具体如下图所示:
4.session域
和Cookie一样,去买一件上衣,这个时候就会把上衣这个对象存入的开辟的Session空间中, Session空间为此对象生成一个唯一的Key值,当再去购买裤子的时候会带着这个唯一的Key值存入到Cookie空间中,同时为它绑定唯一的Key值。因为Session域同样保存在自己浏览器内部,与别人互不干扰,它相较于Cookie而言是服务器技术,较安全。具体如下图所示: