30

我对session secret的重要性感到很困惑。我正在使用 Express 和 Node 进行 Web 开发,目前,我正在尝试实现一个简单的登录。下面的代码取自 Express 中的会话示例。

// Required by session() middleware
// pass the secret for signed cookies
// (required by session())
app.use(express.cookieParser('keyboard cat'));

// Populates req.session
app.use(express.session());

它使用“键盘猫”作为会话秘密。我环顾四周的关于会话秘密的许多事情都建议我将其更改为自定义的东西。我现在有 3 个与此相关的具体问题。

  1. 为什么我以前在使用 PHP 时没有看到这一点?
  2. 会话秘密究竟是用来做什么的?
  3. 假设我更改了会话密钥。我的代码是开源的。在那种情况下,改变它会不会有点多余?我没有看到要求用户提供自定义密钥作为选项。
  4. 我正在考虑生成一个随机 UUID 来填写密钥。这有问题吗?(在安全方面)
4

3 回答 3

42
  1. 因为 PHP 不是 Nodejs。PHP 中的会话管理与节点中的会话管理不同:节点永不消亡,与 PHP 不同,PHP 会不断地由您的服务器守护程序(apache、IIS、您有什么)调用,要求生成一些内容,然后结束其进程。Node 相当于 ApachePHP。
  2. 它用于加密会话 cookie,以便您可以合理(但不是 100%)确定 cookie 不是假的,并且应将连接视为与 express 进行的较大会话的一部分。
  3. 这就是为什么您不将字符串放在源代码中的原因。您将其设为环境变量并将其作为 process.env("SESSION_SECRET") 读入,或者使用.env带有https://npmjs.org/package/dotenv的文件,并确保这些文件永远不会触及您的存储库(svn/git排除/忽略),以便您的秘密数据保持秘密。
  4. 当您的节点应用程序运行时,秘密是不可变的。提出一个长而有趣的句子比 UUID 要好得多,UUID 通常比"I didn't think I needed a secret, but some rando on Stackoverflow told me Express needed one so here we are".

我如何使用会话:

.env 文件(始终在我的 .gitignore 文件中,因此它永远不会访问我的公共存储库):

SECRET="This is my funky secret oh my god it has ninja turtles"

应用程序.js:

var express = require('express'),
    env = (function(){
      var Habitat = require("habitat");
      Habitat.load();
      return new Habitat();
    }()),
    app = express();

app.use(express.compress()); // gzip all the things. If possible.
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.cookieSession({
  key: "mysite.sid",
  // seeing this tells you nothing about the actual secret:
  secret: env.get("SESSION_SECRET"),
  cookie: {
    maxAge: 2678400000 // 31 days
  }
}));
app.use(express.csrf());

该 CSRF 位确保页面请求来自您自己的站点,而不是 cURL 请求或嵌入其他人的网站。http://expressjs.com/api.html#csrf了解更多信息。

于 2013-09-02T04:52:47.253 回答
12

我认为其他答案中遗漏了主要观点,即secret参数是否使会话管理更加安全。在这个 Security.StackExchange 问题中很好地讨论了它:为什么将会话 ID 直接存储在 cookie 中是不安全的?

我建议阅读它(不仅有相关的最高投票答案)。

试图总结一下:如果会话 ID是大随机数,它不会显着减少会话被猜测和劫持的机会,但如果会话 ID是自定义的,比如递增 ID,它显然会有很大帮助,这是在ExpressJS中可能。

用户可以使用他们想要的任何会话 ID。也许有人觉得他们应该使用 SQL 数据库中的自动递增数字,这没关系,因为我们通过签署值来保护他们不知情的决定,延长密钥。

于 2016-08-02T21:12:16.247 回答
3

我的困惑在于服务器端会话和客户端会话之间。在今天之前,我不知道客户端。下面是对差异的清晰解释。

为什么 CherryPy 会话不需要密钥?

考虑到服务器端模型,我很困惑会话中需要加密的地方。

于 2013-09-02T05:36:39.310 回答