Node.js 服务器重启会导致会话丢失。

20

我正在使用Express和Connect中间件开发完全功能的用户注册/认证系统。

app.use(express.session({store: require('connect').session.MemoryStore( {reapInterval: 60000 * 10} ) }))

唯一的问题是每次服务器重启时会丢失会话。

nodemon 检测到文件更改后会重新启动 Node.js。

我该如何保持持久会话?


我在想如何使用JWT来实现持久化会话,而不是使用数据库...?? - Alexander Mills
5个回答

24

您的代码显示您正在使用MemoryStore,该存储是易失性的,在重新启动后会被清除。我建议您使用connect_redis 来保存您的会话。Redis是一种极快的存储方式。

  1. 下载redis
  2. 编译redis: make
  3. 启动服务器: ./redis-server
  4. npm install connect-redis
  5.  

    var connect = require('connect') , RedisStore = require('connect-redis');
    
    connect.createServer(
      connect.cookieParser(),
      // 5 minutes
      connect.session({ store: new RedisStore })
    );
    

这只是为了让您快速入门。如果您想充分利用redis,您应该阅读文档并配置redis。


只是好奇,为什么你在RedisStore中使用ProperCase?是否有NodeJS的惯例或原因? - Clarence Liu
@ClarenceLiu 类名通常选择使用 ProperCase(或CamelCase或其他你想称呼的方式)。 - Domi
啊,很酷,对我来说camelCase以小写字母开头,但我确实喜欢这个约定。 - Clarence Liu

14

我正在尝试使用express.js来使用Redis,谷歌将我带到了这里。express的实现发生了变化:

var express = require('express'),
RedisStore = require('connect-redis')(express);

另一个重要的事情是express配置的顺序。

app.configure(function(){

    app.enable('strict routing'); // removes trailing slash
    app.set('views', __dirname + '/views');
    app.set('view engine', 'jqtpl');
    app.register('.html', require('jqtpl').express);
    app.use(express.favicon());
    app.use(express.methodOverride());
    app.use(express.compiler({src: __dirname + '/public', enable: ['sass']}));
    app.use(express.static(__dirname + '/public'));
    app.use(app.router);
    app.use(express.bodyParser());
    app.use(express.cookieParser());
    app.use(express.session({secret: _.config.secret, store: new RedisStore}));

});

cookieParser 和 session 的配置需要放在配置的最后,cookieParser 必须紧接在 express.session 之前。

希望这可以帮到你,我也曾遇到这两个问题。


8

6

另外,如果您正在使用Express,当告诉应用程序使用Redis中间件时,需要提供一个密钥。

因此,请按照Alfred上面的步骤操作,但是执行以下操作...

var express = require( 'express' );
var RedisStore = require('connect-redis');

app.use( express.cookieParser() );
app.use( express.session( { secret: "keyboard cat", store: new RedisStore }));

现在你需要添加 require('connect-redis')(express) - 否则你会得到一个 TypeError: Cannot read property 'session' of undefined。(https://github.com/visionmedia/connect-redis/issues/24) - Christian Landgren

1

当节点死亡时,我想你正在使用的内存存储也会死亡。

将会话持久化到磁盘上吗?


3
由于 Redis 将会话处理在额外的进程中,因此即使节点崩溃和重启,会话也能得以保存。但如果 Redis 崩溃,会话也会相应地中断。 - ezmilhouse

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接