【问题标题】:Where is the express-session cookie hidden?快速会话 cookie 隐藏在哪里?
【发布时间】:2018-07-12 23:16:37
【问题描述】:

我的express-session 工作正常,我用一个非常短的 cookie 最大使用时间(10 秒)对其进行了测试,它按预期工作:

app.use(session({
  secret: 'xxx',
  resave: false,
  saveUninitialized: true,
  cookie: { secure: true, maxAge: 10000 }
}));

奇怪的是,我在 Chrome 开发者工具中的任何地方都找不到 cookie。 express-session设置的cookie隐藏在哪里?

更新 #2: See my own answer 如果您想知道在哪里可以看到 cookie,如果您将 ajax request 发送到另一个域上的 express server

更新 - 我的快速服务器上的会话管理:

app.post('/verify', function(req, res){
    let out = [];

    if(!req.session.userId){

        if(typeof req.body.token !== 'undefined'){
            admin.auth().verifyIdToken(req.body.token)
            .then(function(decodedToken) {
              let uid = decodedToken.uid;

              if(!req.session.userId){
                  req.session.userId = uid;
              }

              res.send(uid);
              // ...
            }).catch(function(error) {
              // Handle error
              res.send(error);
            });
        }else{
            res.send('no token received');
        }
    }else{
        res.send('already logged in by session with uid: ' + req.session.userId + ' | session id: ' + req.session.id);
    }
});

这就是服务器“启动”的方式:

app.listen(port, function () {
  console.log('Example app listening on port ' + port + '!');
});

问题是会话有效,但我看不到 cookie:

【问题讨论】:

  • 看来,您在代码中使用了http 服务器。但正如您在我的回答中看到的那样,如果您使用cookie.secure,则需要使用https!请验证您的服务器设置以确保或使用不安全的 cookie。
  • @eisbehr 谢谢你,我会试试看的——但是为什么那些黑客仍然可以工作呢? - 那是我不明白的。
  • 嗯,这属于你所说的“它有效”。会话本身将按预期工作。它可以在会话中读取和保存数据。唯一的事情是 cookie 的存储。连接关闭后,您将直接丢失数据。不同浏览器显示相同行为的事实表明某处仍然存在问题......
  • @eisbehr 是的,但据我所知,会话只能由似乎不存在的 cookie 识别。
  • 您是否曾在我的答案中测试过我的示例代码?这也是有效的吗?

标签: javascript node.js express express-session


【解决方案1】:

TL;DR

您可以在 Chrome DevTools 的以下位置找到 Cookie:
Application > Storage > Cookies > URL of the express Server

从哪里开始

为了显示 express 的 cookie 存储正确,我从一个简单的测试服务器开始。请注意,您在问题中使用了cookie.secure = true,这需要与服务器建立https 连接。否则,浏览器会立即删除 cookie。所以让我们使用这个简单的:

let fs = require('fs');

let privateKey  = fs.readFileSync('../../../apache/conf/ssl.key/server.key', 'utf8');
let certificate = fs.readFileSync('../../../apache/conf/ssl.crt/server.crt', 'utf8');
let credentials = {key: privateKey, cert: certificate};

let https = require('https');
let app = require('express')();
let session = require('express-session');

app.use(session({
    secret: 'keyboard cat',
    resave: false,
    saveUninitialized: true,
    cookie: {secure: true, maxAge: 10000}
}));

app.all('*', function(req, res) {
    res.status(200);
    res.setHeader('Content-Type', 'text/html');

    if (!req.session.views) {
        req.session.views = 0;
    }

    req.session.views++;
    res.write('<p>views: ' + req.session.views + '</p>');
    res.end();
});

https.createServer(credentials, app).listen(8080);

正常工作时,您应该能够在浏览器中打开https://localhost:8080 并看到类似views: 1 的内容。

刷新浏览器时,每次请求都应增加计数。没有请求的 cookie 的最大生命周期为 10 秒。在此时间之后,计数将再次从1 开始。

在 DevTools 中哪里可以找到 Cookie

在 10 秒的生命周期内,您可以在 Chrome DevTools 内的Application > Storage > Cookies > URL of the express Server 下看到 cookie。当然,这种情况下 cookie 的值是加密的。

使用 AJAX 时的一些提示

正如您稍后提到的,您的问题属于AJAX 电话。一般来说,都和上面的一样。您甚至可以在 Storage > Cookies 选项卡中立即看到 AJAX 创建的 cookie。但前提是您的 cookie 配置正确并且属于同一个域。

Storage 选项卡中的 cookie 由 cookie domain 和 cookie path 选择。该列表将显示并更新与该模式匹配的所有内容。因此,在您的示例中,cookie 似乎与请求页面不匹配。

正如我在您的页面上看到的,您正在使用 ULR https://***.firebaseapp.com 打开页面并向 https://***.herokuapp.com/verify/ 发出 AJAX 请求,这是两个完全不同的域。这就是您在Storage 标签中看不到它们的原因!

如果这仍然不起作用,则在使用同一域时,请在您的 session 配置中设置 cookie.path。然后一切都应该如上所述。 ;)

【讨论】:

  • 哇 - 谢谢你的详细回答!我的会话按预期工作-“问题”或“奇怪的事情”是,我仍然无法在开发人员工具中看到它们。我在那里看到我的域,但没有设置 cookie。
  • 我知道 Chrome 不在那里显示 cookie 的唯一方法是每当页面被阻止保存 cookie 时。然后行为就像你描述的那样,它通常工作,你看到域但没有会话cookie。也许在 chrome 中检查你的 cookie 设置,或者用 firefox 测试同样的东西。以下是检查 cookie 设置的方法:support.google.com/accounts/answer/…@low_rents
  • 但是当页面被阻止时,我认为我的会话根本无法工作......但它们确实有效。还尝试使用 firefox - 那里也看不到 cookie。我将使用更多快速服务器的代码来更新我的问题。也许这有帮助。
  • 很抱歉反应迟了 - 但这只是我的“爱好项目”,所以我不能 24/7 全天候工作。如果我将 cookie 域设置为 https://***.firebaseapp.com 并将 cookie 路径设置为 / 它仍然不起作用 - 更糟糕的是 - 会话行为根本不起作用。我还尝试在每个可能的组合中设置没有https:// 和路径的域。
  • AFAIK 你不能只是将 cookie 域更改为另一个域。如果 cookie 域和真实域不匹配,浏览器将拒绝这是不安全的。您需要更改请求 url 或生活,因为您无法在存储选项卡中看到 cookie。 ;) @low_rents
【解决方案2】:

我现在发现我的问题缺少一些重要信息。
我没有提到的是,请求是通过ajax发送的。
在 Chrome 中(我猜在大多数浏览器中)你看不到那些显示“站点”cookie 的“连接 cookie”。您可以在 ajax 请求的详细信息下的连接选项卡中看到它们。

【讨论】:

  • 你的回答只说对了一半。一般来说,它与 AJAX 无关。请查看我对您的问题的更新答案...
猜你喜欢
  • 2016-08-08
  • 2017-01-07
  • 2016-09-01
  • 2014-04-16
  • 2016-11-30
  • 2020-10-20
  • 1970-01-01
  • 2021-02-21
  • 1970-01-01
相关资源
最近更新 更多