博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
管理用户状态——Cookie与Session
阅读量:4089 次
发布时间: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}"则是利用当前用户的属性值渲染链接。

更多文章请访问

你可能感兴趣的文章
Mysql复制表以及复制数据库
查看>>
进程管理(一)
查看>>
linux 内核—进程的地址空间(1)
查看>>
存储器管理(二)
查看>>
开局一张图,学一学项目管理神器Maven!
查看>>
Android中的Binder(二)
查看>>
Framework之View的工作原理(一)
查看>>
Web应用架构
查看>>
设计模式之策略模式
查看>>
深究Java中的RMI底层原理
查看>>
用idea创建一个maven web项目
查看>>
Kafka
查看>>
9.1 为我们的角色划分权限
查看>>
维吉尼亚之加解密及破解
查看>>
DES加解密
查看>>
TCP/IP协议三次握手与四次握手流程解析
查看>>
PHP 扩展开发 : 编写一个hello world !
查看>>
inet_ntoa、 inet_aton、inet_addr
查看>>
用模板写单链表
查看>>
用模板写单链表
查看>>