世界上任何一个拥有用户数据的 web 应用都必须处理 sessions。作为一名开发者,我们必须要知道它们是什么以及如何处理它们。
在这篇文章中,我想要分享的是:
- session 是什么?
- session 如何存储数据?
- 你如何决定存放 session 数据的位置?
- 在 sessions 工作时,你必须意识到的安全性上的影响有哪些?
在一些示例代码中,我将会运用 session npm module ,它很有可能是最常见的 session 库。
session 是什么?
session 是存储你通过请求获取到的数据的地方。每一个访问你网站的用户都有一个唯一的 session。当他们浏览你应用的时候,你就可以使用 session 去存储和获取用户数据。
session 对 web 应用开发来讲是必须有的,因为 session 允许应用去存储状态。基于用户在页面 A 上的一个动作,我们就可以展示出一个不同的页面 B。如果没有 session,应用将是无状态的,而且很无用。
这里展示了你如何使用 Express 去建立一个简单的 session
import express from 'express';
import session from 'express-session';
var app = express();
app.use(session());
如果你的应用已经有了可使用的 sessions, 你可以在一个路由处理中设置一些数据:
app.use(session({ secret: 'this-is-a-secret-token', cookie: { maxAge: 60000 }}));
// Access the session as req.session
app.get('/', function(req, res, next) {
var sessData = req.session;
sessData.someAttribute = "foo";
res.send('Returning with some text');
});
在另一个路由处理中读到它:
app.get('/bar', function(req, res, next) {
var someAttribute = req.session.someAttribute;
res.send(`This will print the attribute I set earlier: ${someAttribute}`);
});
sessions 可以用不同的方式存储它们的信息。存储 session 数据最受欢迎的方式有:
- 在应用内存中
- 在 cookie 中
- 在内存缓存中
- 在数据库中
使用应用内存存储 session 数据
这是常见的最简单的存储方式,但在生产环境中不用。
用这种方式存储从根本上意味着数据在应用执行时间中的有效期内被存储,一旦你的 web 应用服务器宕机了或停止运行了,所有的 session 数据都会被移除。
在内存中存储 session 数据也会导致内存泄露。当你的应用保持运行的时候,越来越多的内存被占用,直到应用因为内存不足而退出。
为了开发的目的,把 session 数据存在内存中经常很有用。然而,这儿还有更好的存储 session 数据的方式。
使用 cookie 存储 session 数据
cookie 通常是从 web 服务器发送到你的 web 浏览器上的一小块数据。它允许服务器存储一个具体用户相关的信息。
cookies 的一种常见用法就是存储 session 数据,它的工作流程是:
1、服务器发送一个 cookie 给 web 浏览器,并且在客户端存储一段时间(称为 expiration time)。
2、当用户随后向 web 服务器发起一个请求时,这个 cookie 会和这个请求一起发送,服务器可以读到 cookie 中包含的信息。
3、如果需要的话,服务器可以修改 cookie,然后再把它返回给浏览器。
每次你发起一个请求,你的浏览器都会把 cookie 发送给服务器,直到 cookie 过期为止。
类似 express-session 这样的模块会给你提供一个友好的 API 和 sessions 一起工作(让你可以获取 & 设置 session 里的数据 ),但是在底层,它可以通过 cookie 保存和恢复这个数据。
Express-session 也提供一些方法来保证你 cookies 的安全性。我们在这不会讲述安全细节,但是我推荐你通过阅读文档来详细研究安全细则。这对于确保你应用里的 cookie 信息不被暴露是非常重要的。使用 cookie 存储 session 数据也带来了一些问题:
1、可以存储的数据量很小,大约只有 4kb。
2、因为每次发送请求都会携带 cookie,如果你在 cookie 中存储了一堆数据,它将会增加请求中的数据量,从而导致你的网站性能降低。
3、如果攻击者弄清楚了你的 cookies 是如何加密的,那么你的 cookies 就危险了。攻击者将能读到 cookies 中存储的信息,这可是用户敏感信息啊!
使用内存缓存存储 session 数据
内存缓存是可以存储一小堆键值数据的地方。使用内存缓存存储 session 信息的最出名的两个例子就是 Redis 和 Memcached。在内存缓存中存储 session 数据的时候,服务器仍然使用 cookie,但是这个 cookie 只包含一个唯一的 sessionId。这个 sessionId 在服务器对储存库进行查找的时候使用。
使用内存缓存的时候,你的 cookie 只包含一个 session ID。它避免了私人用户信息被暴露在 cookie 中的危险。使用内存缓存存储 session 数据的优点:
1、基于键值对数据存储,便于查找。
2、它们和你的应用服务器分隔开来。这种分隔降低了依赖。
3、单独一个内存存储可以服务好多个应用。
4、通过移除老的 session 数据来自动管理内存。
当然,这种存储方式也有一些缺点:
1、它们是另一台服务器,需要进行建立和管理。
2、对一些小应用来说可能是杀鸡用了牛刀。一般这种情况的话,使用数据库存储或者 cookies 存储效果更好。
3、重置缓存的唯一办法就是移除所有存储在它里面的 sessions。
下面的示例告诉你如何来用 express-session 来建立一个类似 Memcached 的内存缓存,通过 connect-memcached 模块。
var express = require('express');
var session = require('express-session');
var cookieParser = require('cookie-parser');
var app = express();
var MemcachedStore = require('connect-memcached')(session);
app.use(cookieParser());
app.use(session({
secret : 'some-private-key',
key : 'test',
proxy : 'true',
store : new MemcachedStore({
hosts: ['127.0.0.1:11211'], //this should be where your Memcached server is running
secret: 'memcached-secret-key' // Optionally use transparent encryption for memcache session data
})
}));
使用数据库存储 session 数据
最后,我们谈一下在传统的数据库中存储 session 数据,比如 MySQL 和 PostgreSQL。在大多数情况下,它以一种类似于在内存中存储 session 数据的方式来工作。session cookie 仍然只含有一个 sessionId。在这种情况下,它将会匹配数据库里的 session 表中的第一个 key 值。总的来讲,我不推荐使用数据库来存储 session 数据,我这么做的唯一的理由是它需要花费大量精力去建立 Memcached 或 Redis。从数据库中恢复数据比用内存缓存恢复要慢的多,因为数据存储在硬盘上,而不是内存中。当你把 session 数据存在数据库里的时候,你会被数据库暴击的。。。。另外,你必须自己全权管理老的 session 数据。如果你没有移除老的 session 数据,你的数据库将被成千上万条无用数据行占用。这里有许多数据库存储,你可以使用 express-session。在 README 中查看完整列表。
你应该在哪存储你的 session 数据?
我们讨论了常用的三种方式存储来存储你的 session 数据。那么你应该在哪存储你的 session 数据呢?
总的来说,我遵循这个规则:“内存第一(译者注:这里应该是指内存缓存),cookie 第二,最后是数据库”。
如果你使用 Memcached 或 Redis,我会和你相伴。如果不是,把你的 session 数据存在 cookie,但一定要确保你私钥的安全。最后,你可以把你的 session 数据存在数据库里,但一定要有一个移除老 session 数据的计划。
原文地址:http://nodewebapps.com/2017/0...