Express session 的基本用法

Express session 的基本用法

Flying
2017-05-28 / 0 评论 / 139 阅读 / 正在检测是否收录...

express-session 中间件将会话数据存储在服务器上;它仅将会话标识(而非会话数据)保存在 cookie 中。从 1.5.0 版本开始, express-session 不再依赖cookie-parser,直接通过 req/res 读取 / 写入,默认存储位置内存存储(服务器端)。

sesstion-express.svg

Session 概述

Session 是另一种记录客户状态的机制,不同的是 Cookie 保存在客户端浏览器中,而 Session 保存在服务器上。当浏览器访问服务器并发送第一次请求时,服务器端会创建一个 Session 对象,生成一个类似于 key/value 的键值对, 然后将 key(cookie)返回到浏览器(客户)端,浏览器下次再访问时,携带 key(cookie),找到对应的 Session 值(value)。

注意:cookie 中不保存会话数据,只保存会话 ID。会话数据存储在服务器端。

原理

基本原理是服务端为每一个 Session 维护一份会话信息数据, 而客户端和服务端依靠一个全局唯一的标识来访问会话信息数据。用户访问 web 应用时,服务端程序决定何时创建 Session,创建 Session 可以概括为三个步骤:

1. 生成全局唯一标识符(sessionid);
2. 开辟数据存储空间。一般会在内存中创建相应的数据结构,但这种情况下,系统一旦断电,所有的会话数据就会丢失,如果是电子商务网站,这种事故会造成严重的后果。不过也可以写到文件里甚至存储在数据库中,这样虽然会增加 I/O 开销,但 Session 可以实现某种程度的持久化,而且更有利于 Session 的共享;
3. 将 Session 的全局唯一标示符发送给客户端。

Session vs cookie

  • 应用场景:Cookie的典型应用场景是 Remember Me 服务,即用户的账户信息通过 Cookie 的形式保存在客户端,当用户再次请求匹配的 URL 的时候,账户信息会被传送到服务端,交由相应的程序完成自动登录等功能。当然也可以保存一些客户端信息,比如页面布局以及搜索历史等等。Session 的典型应用场景是用户登录某网站之后,将其登录信息放入 Session,在以后的每次请求中查询相应的登录信息以确保该用户合法。当然还是有购物车等等经典场景;
  • 安全性:Cookie 将信息保存在客户端,如果不进行加密的话,无疑会暴露一些隐私信息,安全性很差,一般情况下敏感信息是经过加密后存储在 cookie 中,但很容易就会被窃取。而 Session 只会将信息存储在服务端,如果存储在文件或数据库中,也有被窃取的可能,只是可能性比 Cookie 小了太多。Session 安全性方面比较突出的是存在会话劫持的问题,这是一种安全威胁。总体来讲,Session 的安全性要高于 Cookie;
  • 性能:Cookie存储在客户端,消耗的是客户端的 I/O 和内存,而S ession 存储在服务端,消耗的是服务端的资源。但是 Session 对服务器造成的压力比较集中,而 cookie很好地分散了资源消耗,就这点来说,Cookie 是要优于 Session 的;
  • 时效性:Cookie 可以通过设置有效期使其较长时间内存在于客户端,而 Session 一般只有比较短的有效期(用户主动销毁 Seasion 或关闭浏览器后引发超时);
  • 其他:Cookie 的处理在开发中没有 Session 方便。而且Cookie 在客户端是有数量和大小的限制的,而 Session 的大小
    却只以硬件为限制,能存储的数据无疑大了太多。

简单来说,Session 相比 Cookie 要更安全一些。由于 Session 保存到服务器上,所以当访问量增多的时候,会比较占用服务器的性能。单个 cookie 保存的数据大小不能超过 4K,很多浏览器都限制一个站点最多保存 20 个 cookie。Session 没有这方面的限制。Session 是基于 Cookie 进行工作的。

Session工作的大致步骤

1. 用户提交包含用户名和密码的表单,发送 HTTP 请求。
2. 服务器验证用户发来的用户名密码。
3. 如果正确则把当前用户名(通常是用户对象)存储到 redis 中,并生成它在 redis中的I D。这个 ID 称为Session ID,通过Session ID可以从 Redis 中取出对应的用户对象, 敏感数据(比如authed=true)都存储在这个用户对象中。
4. 设置 Cookie 为 sessionId=xxxxxx|checksum 并发送 HTTP 响应, 仍然为每一项 Cookie 都设置签名。
5. 用户收到 HTTP 响应后,便看不到任何敏感数据了。在此后的请求中发送该 Cookie 给服务器。
6. 服务器收到此后的 HTTP 请求后,发现 Cookie 中有 SessionID,进行放篡改验证。
7. 如果通过了验证,根据该 ID 从Redis中取出对应的用户对象, 查看该对象的状态并继续执行业务逻辑。

使用 express-session

express-session 中间件将和其他中间件一样,使用比较简单。

  • 安装
npm install express-session
  • API
const express = require('express')
const session = require("express-session");

const app = express()
app.use(session)
  • 常用参数

express-session 的常用参数及作用如下表:

参数作用
secret一个String 类型的字符串,作为服务器端生成 session 的签名
name返回客户端的 key 的名称,默认为 connect.sid,也可以自己设置
resave强制保存session 即使它并没有变化, 默认为 false
saveUninitialized强制将未初始化的 session 存储。默认为 true
cookie设置返回到前端 key 的属性,默认值为{ path: '/', httpOnly: true, secure: false, maxAge: null }
rolling在每次请求时强行设置cookie,这将重置 cookie 过期时间。默认为 false

参考实例

访问 codesandbox 查看 完整实例代码及最终效果

本实例中,我们定义了一个名为 sample 的 session 的签名,将它的 cookie key 值设置为 1 小时后过期,每次请求不重置 cookie 过期时间。

我们使用了一个 session 变量 userame,用户点击 Login In 时会将变量 userame 设置成 riafan;点击 Login In 时会将变量 userame 设置为空。用户下次进入页面时会根据变量 userame 的值显示相应的提示信息。

相关教程

3

评论 (0)

取消