博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
管理用户状态——Cookie与Session
阅读量:4094 次
发布时间:2019-05-25

本文共 2827 字,大约阅读时间需要 9 分钟。

管理用户状态—— 由发表在

利用Cookie跟踪用户状态

博客系统由多个功能(页面)组成:

  1. 首页——包含博客功能简介、用户列表
  2. 用户博客列表——包含某一用户的文章列表
  3. 文章详细页面——包含某一篇文章的标题、详细内容、创建时间等信息
  4. 创建文章页面——包含文章标题、内容的表单

在创建文章时,除了标题和内容,还需要知道是谁创建的这篇文章,当然我们不能够在表单中添加一个输入框让用户输入自己是谁——因为用户的身份很有可能被伪造。一个办法是在每一个页面被访问之前,我们要求用户输入在网站注册时输入的用户名/密码进行验证,如果验证通过才可以访问对应的页面。正好可以完成这样的功能,可是这样实在是太麻烦了,没访问一个页面都需要用户进行输入。

我们知道HTTP协议本身是无状态的,也就是说任何完全一致的请求都将会得到完全相同的返回。但是我们可以认为的在HTTP请求中定义状态。

是由客户端保存的小型文本文件,其内容为一系列的键值对,在浏览器访问同一个域名的不同页面时,会在HTTP请求中附上Cookie。

Cookie可以保存在内存中(关闭浏览器即消失),也可以保存在硬盘中(到达过期时间后消失)。另外,Cookie也是一个比较古老的东西,与JavaScript同样由网景公司发明,现已被标准化为RFC2109。

我们正是通过Cookie的这些特性来实现用户状态的保存的,每当用户访问一个网站时,服务器程序会分配给它一个唯一的id,这个id就是设置在Cookie中的,以打开浏览器第一次访问为例,因为是打开浏览器后第一次访问,所以请求头中不会有任何网站相关的Cookie存在,这时服务器会随机分配的一个字符串作为用户的id并放在Cookie中:

Set-Cookie:JSESSIONID=9074327855952DA4A296B67685523812; Path=/; HttpOnly

这里没有指定Cookie的过期时间(Expire),那么当浏览器关闭后,Cookie自动失效,从获取网站的Cookie到浏览器关闭的这个周期,被称为一个会话——Session。那么在这个会话中,在同一浏览器中任何一次对tianmaying.com的访问,都会带上这个名字为JSESSIONID(Servlet默认的名字)的Cookie值(在服务器上随机生成的字符串,服务器并会将其保存下来)。

可以简单地这样理解,服务端建立了一个Map<String, Object>,对于每一个请求都可以拿到Cookie中保存的JSESSIONID值,那么服务器程序可以往这个Map里写入任何对象:

map.put(JSESSIONID, 
);

那么在这一次会话中,不管是怎样的请求,都可以访问到这个Map中的对象。而服务器保存的这个Map,也被称为)。Session是一种服务器端保存用户状态的技术,它最常见的实现方式是在Cookie中加入一个字段存储Session ID;但同时Cookie并不是实现Session的唯一手段,在URL中通过参数来保存Session ID同样也是可行的。

用户登录

在注册用户后,用户需要登录网站来确认自己的身份,登录的方式就是在HTML表单中填入用户名和密码并提交给服务器进行验证。在浏览器的一次Session会话中,Cookie中的JSESSIONID保持不变,所以登录成功(服务器端通过验证)后,我们可以在服务端Session中放入当前的用户对象,这样以后访问任何URL,在对应的JSP/Servlet中都能轻易的拿到它。以下是一个多用户访问的Web应用示意图:

可以看到,每一个用户都有一个自己的Session。而在JSP/Servlet中,通过API可以很容易的获取到当前用户的Session并将状态信息放入其中。

在Servlet中设置Session属性值

以用户登录为例:

@WebServlet("/account/login")public class LoginController extends HttpServlet {    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        String username = req.getParameter("username");        String password = req.getParameter("password");        User user = Data.getByUsername(username);        if (user == null || !user.getPassword().equals(password)) {            //登录不成功,返回错误信息        } else {            req.getSession().setAttribute("user", user);            //返回登录成功信息        }    }}

获取Session的API是req.getSession(),接下来通过getAttribute()setAttribute()方法就可以像一个Map一样获取/设置Session的属性值。这里我们将User对象放入了Session,名字为user

在JSP中获取Session属性值

在渲染页面时,很多时候需要获取当前用户的信息,例如导航栏的显示:

  1. 根据用户是否登录显示不同的信息
  2. 如果用户已经登录,需要根据当前用户信息显示某些内容——例如“我的首页”的链接

在JSP Scriptlet中可以通过session对象来获取Session的属性值,如果使用EL表达式,那么需要使用${sessionScope}得到Session对象,下面以导航栏为例:

${sessionScope.user != null}作为判断条件表示当前用户已经登录;href="userPosts?username=${sessionScope.user.username}"则是利用当前用户的属性值渲染链接。

更多文章请访问

你可能感兴趣的文章
用两个栈实现一个队列
查看>>
Error: member names cannot be the same as their enclosing type
查看>>
httprunner 使用总结
查看>>
记一条distinct 语句的优化。
查看>>
学习总结(三十)
查看>>
【手记】解决VS2010宏功能报错
查看>>
HashMap实现原理及源码分析
查看>>
计算机基础概念
查看>>
在C#中使用官方驱动操作MongoDB
查看>>
如何编写跨平台的Java代码
查看>>
Tastypie与Backbone交互
查看>>
C# 数据库删除操作错误报错 System.Data.SqlClient.SqlException (0x80131904)
查看>>
字符编码
查看>>
mysql 语句总结
查看>>
Git 的是使用入门
查看>>
nginx在 window下 自动退出 php-cgi
查看>>
.net 按比例显示图片的缩略图
查看>>
E: 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系。...
查看>>
2016/05/19 thinkphp 3.2.2 文件上传
查看>>
java反射学习总结
查看>>