【问题标题】:Session updates not persisting between requests - nodejs/expressjs/redis/heroku会话更新不在请求之间持续存在 - nodejs/expressjs/redis/heroku
【发布时间】:2014-02-12 22:40:10
【问题描述】:

我正在使用 redis 将我的会话存储在 expressjs 中。它在本地运行时运行良好,甚至在部署在 heroku 上时大部分时间都可以运行。问题是经常(当部署在 heroku 上时)我看到我的会话更新丢失了。

例如一个用户登录到我的网站,我将他们的用户对象添加到会话中:

req.session.user = user;

但是(有时)当我稍后(在不同的请求中)尝试检索对象时,它不存在

//sometimes this is empty, even though I've just set it
var currentUser = req.session.user;

我如下初始化会话存储

if (process.env.REDISTOGO_URL) {
    console.log('Connecting to redis:' + process.env.REDISTOGO_URL);
    var rtg = require('url').parse(process.env.REDISTOGO_URL);
    var redis = require('redis').createClient(rtg.port, rtg.hostname);
    redis.auth(rtg.auth.split(':')[1]);
} else {
    console.log('Connecting to local redis');
    var redis = require('redis').createClient();
}

//sessions
app.use(express.cookieParser('secret key for cookie monster')); //used by session
var RedisStore = require('connect-redis')(express);
app.use(express.session({
    store: new RedisStore({
        client: redis
    })
}));

有什么想法吗?我是否需要对会话数据进行某种刷新(或显式保存)?

【问题讨论】:

  • '稍后',你确定现在是在上一个请求完成之后吗?
  • 当然可以,因为我的登录逻辑在完成之前不会加载下一页。谢谢你的想法

标签: node.js session heroku express redis


【解决方案1】:

我要劫持这个古老的问题,让你们了解我是如何解决这个问题的。

TL;DR

您可能已将 REDIS_URL 值从您的 Heroku 应用配置复制到您的本地 .env 文件中。 Heroku 会随着时间的推移改变这个值,现在这已经发生了。

解决方案是将新的 REDIS_URL 值从 Heroku 应用配置复制到本地 .env 文件或使用另一个 Redis 实例进行本地开发。

您可能已经尝试过的方法

可能您的会话几天前还在工作,您尝试并验证了所有常见的嫌疑人,以解决这个突然出现的问题。

一切都无济于事。最后,当您从会话配置中删除 RedisStore 位时,会话再次工作。

const session = require('express-session');
const RedisStore = require('connect-redis')(session);
// ...
server.set('trust proxy', 1);
server.use(
    session({
        // store: new RedisStore({
        //     url: process.env.REDIS_URL,
        // }),
        secret: process.env.SESSION_SECRET,
        resave: false,
        saveUninitialized: true,
        cookie: {
            path: '/',
            httpOnly: true,
            secure: false,
            maxAge: null,
        },
    })
);

发生了什么?

后来我明白了删除 Redis 存储是如何解决问题的。我在我的 Heroku 应用程序配置提供的本地 .env 文件中使用了 REDIS_URL。我了解到REDIS_URL on the Heroku app may change over time

为了让 Heroku 为您管理此插件并回复 各种操作情况,REDIS 配置变量可能会在 随时。依赖 Heroku 应用程序之外的配置变量可能 如果值发生变化,您必须重新复制该值。

(强调我的)

所以在我的情况下,这实际上已经发生了,我的本地 .env 文件仍然具有旧的 REDIS_URL 值。实际上,无法创建会话存储,因为它尝试连接到不存在的服务。这就是为什么删除 RedisStore 从而回退到默认的 MemoryStore 来解决问题的原因。

防止再次发生

我在 redislabs.com 创建了一个帐户并创建了一个免费的 Redis 实例。我现在在本地 .env 文件中使用的那个 url。该网址不会改变(我希望)。

【讨论】:

  • 不知道删除 Redis 存储如何解决问题。现在您只是使用默认的 MemoryStore,它会泄漏内存并且不会扩展到单个测功机之外。
  • 我在本地 .env 中使用了由 Heroku 应用配置提供的 REDIS_URL。但是 Heroku 应用程序上的那个 URL 实际上会随着时间而改变。我的本地 .env 文件仍然有旧的 REDIS_URL,因此无法创建会话存储。这就是为什么删除 RedisStore 从而回退到默认的 MemoryStore 来解决问题的原因。我稍后会更新我的答案以反映这一发现。
  • 我已经重写了我的答案
猜你喜欢
  • 2013-09-19
  • 1970-01-01
  • 1970-01-01
  • 2014-08-28
  • 2019-04-19
  • 2011-03-01
  • 2015-01-28
  • 1970-01-01
相关资源
最近更新 更多