一.引言
日常生活中,当我们访问一个网站时,输入账号密码登录之后,离开一段时间回来发现网站仍然处于登录状态,但是有时我们回来就会显示再次登录了,或者有时我们关闭浏览器页面,下次再次访问还会显示登录成功,但是当我们换一个浏览器就会显示重新输入账号密码才可以进行登录,不论日常生活还是我们网安研究人员或多或少都会有点理解,但是其原理是什么呢?
在我们熟悉的servlet中有Cookie与HttpSession对象(会话对象),servlet可以理解为连接前端与服务端的接口,我们浏览界面时将请求通过servlet发送至服务端,之后服务端再通过servlet将响应包呈现到我们面前,这就是servlet工作的基本原理。
二.Cookie对象
Cookie是浏览器提供的一种技术,通过服务器的程序能将一些只须保存在客户端,或者在客户端进行处理的数据,放在本地的计算机上,不需要网络连接,因而提高网页处理的效率,并且能够减少服务器的负载,但是由于Cookie是服务器端保存在客户端的信息,所以其安全性也是很差的。例如常见的记住密码就可以通过Cookie来实现。
servlet中有一个专门操作Cookie的类javax.servlet.http.Cookie,随着服务器的响应发送给客户端,保存在浏览器,当下次访问时再将Cookie带回服务器。
Cookie格式:键值对用"="链接,多个键值对利用":"隔开
当我们利用servlet创建Cookie对象时,会利用键值对的形式加入response对象中来完成创建:
//创建Cookie对象Cookie cookie = new Cookie("name","admin")//发送Cookie对象response.addCookie(cookie);
创建完成之后发送cookie对象给浏览器来进行查看:
刚才说到,当我们长时间不登陆或者几天不登陆,也可以直接免密登录,这就涉及到Cookie对象的到期时间的设置,默认当前浏览器关闭即失效,我们也可以手动设定cookie到期时间(通过到期时间计算),通过setMaxAge(int time)方法设定cookie最大有效时间,以秒为单位。
到期时间的取值
- 负整数
若为负数,表示不存储该cookie.
cookie的maxAge属性的默认值为-1,表示只在浏览器内存中存活,一旦关 闭浏览器窗口,那么cookie就会消失。
- 正整数若大于0的整数,表示存储的秒数表示cookie对象可存活指定的秒数,当生命大于0时,浏览器会把Cookie保存到硬盘上,就算关闭浏览器,就算重启客户端电脑,cookie也会存活响应的时间。
- 零若为零,则删除此cookiecookie生命等于0是一个特殊的值,它表示cookie被作废!也就是说,如果原来浏览器已经保存了这个Cookie,那么可以通过Cookie的setMaxAge(0)来删除这个Cookie。无论是在浏览器内存中,还是在客户端硬盘上都会删除这个Cookie.
注:到期时间是指当前时间加有效时间,当到期时间为-1时,即关闭时,到期时间为当前时间-1,所以当到期时间为-1时,浏览器关闭时就会删除此cookie。
而且需要注意的是,每个浏览器的Cookie都是一个文件,所以当我们换一个浏览器时就会显示重新登录。
三.HttpSession对象
HttpSession对象是javax.servlet.http.HttpSession的实例,该接口不像HttpServletRequest或HttpServletResponse还存在一个父接口,该接口只是一个纯粹的接口。这因为session本身就属于HTTP协议的范畴。 对于服务而言,每一个连接到它的客户端都是一个Session,servlet容器使用此接口创建HTTP客户端的HTTP服务器之间的会话,会话将保留指定的时间段,跨多个连接或者来自用户的页面请求,一个会话通常对应于一个用户,该用户可能多次访问一个站点。可以通过此接口查看和操作有关某个会话的信息,比如会话标识符,创建时间和最后一次访问时间,在整个Session中,最重要的就是属性的操作。 Session无论客户端还是服务器端都可以感知到,若重新打开一个新的浏览器,则无法取得之前设置的session,因为每一个session只保存在当前的浏览器中,并在响应的页面取得。 Session的作用就是为了标识一次会话,或者说确认一个用户;并且在一次会话(一个用户的多次请求)期间共享数据。我们可以通过request.getSession()的方法,来获取当前会话的session对象。
我们学习的时候有时会有一个误区,浏览器验证中session与cookie或者token到底有何关系呢,如下:
Session既然是为了标识一次会话,那么此次会话就应该有一个唯一的标识,这个标志就是sessionid。
每当一次请求到达服务器,如果开启了会话(访问了session),服务器第一步会查看是否从客户端回传一个名为JSESSIONID的cookie,如果没有则认为这是一次新的会话,会创建一个新的session对象,并用唯一的sessionid为此次会话做一个标识,如果有JESSIONID这个cookie回传,服务器则会根据JESSIONID这个值去查看是否含有id为JESSION值的session对象,如果没有则认为是一个新的会话,返回该session对象,数据达到共享。
这里提到一个叫做JESSIONID的cookie,这是一个比较特使的cookie,当用户请求到达服务器时,如果访问了sesion,则服务器会创建一个名为JESSIONID,值为获取到的session(无论时获取到的还是新创建的)sessionid的cookie对象,并添加到response对象中,响应给客户端,有效时间为关闭浏览器。
所以Session的底层依赖Cookie来实现。
如此可见,session与cookie并不是一种东西,但是我们建立会话时就会建立一个验证身份名为sessionid的cookie对象也就是jsession,来保障我们会话的安全。现在知道其实cookie对象的作用是很大的。
而当我们的会话销毁时也就是关闭浏览器时,session就会自动销毁。