简单的Node / Express应用无法识别会话存储

时间:2018-12-29 17:36:29

标签: javascript express session redis express-session

我有一个非常小的Express应用程序来说明我遇到的问题。

我正在将connect-redis用作我的快速应用程序上的会话存储。我在连接时遇到了问题。只需打印出req.session.store就会得到undefined,如下所示:

const session = require('express-session')
const app = require('express')()
const RedisStore = require('connect-redis')(session);

const isDev = process.env.NODE_ENV !== 'production'

app.use(session({
  store: new RedisStore({
    host: 'localhost',
    port: 6379
  }),
  secret: 'super-secret-key', // TBD: grab from env
  resave: false,
  saveUninitialized: false,
  cookie: {
    maxAge: 1000 * 60 * 60 * 24,
    secure: !isDev, // require HTTPS in production
  }
}))

app.get('/', (req, res) => {
  console.log('**testing**')
  console.log(req.session.store)
  res.send('rendering this text')
})

app.listen(3001, () => {
  console.log('listening on 3001')
})

此输出为:

listening on 3001
**testing**
undefined

store属性中,除了当前的urlclient方法之外,我还尝试通过host属性和port属性进行连接

我也没有看到任何错误,所以我不确定为什么store始终是未定义的。

这个我想念什么?

,我确实使用redis-server开始redis,并且能够通过其他客户端连接到它


更新1
另外,我确实查看了this StackOverflow,有些人认为它很有用。 问题是,从1.5>的{​​{1}}版本开始,它说您不需要cookie-parser模块,所以我不认为这是问题所在。

3 个答案:

答案 0 :(得分:7)

req.session将仅具有为会话设置的属性,而您从未设置名为store的会话属性。以下是RedisStore会话正常工作的示例代码

const express = require('express');
const app = express();
const session = require('express-session');
const RedisStore = require('connect-redis')(session);

const redis = require('redis');
const client = redis.createClient({
  host: '127.0.0.1', 
  port: 6379
});
client.on('error', function (err) {
  console.log('could not establish a connection with redis. ' + err);
});
client.on('connect', function (err) {
  console.log('connected to redis successfully');
});

app.use(session({
  store: new RedisStore({client: client}),
  secret: 'super-secret-key',
  resave: true,
  saveUninitialized: true,
  cookie: {
    ttl: 30 * 10000,
    httpOnly: true,
    secure: false
  }
}));

app.get('/', (req, res) => {
  client.get('user', (err, data) => {
    console.log('data in redis:', data)
  });
  res.status(200).send('OK');
});

app.get('/login', (req, res) => {
  if (req.session.user) {
    res.redirect('/')
  } else {
    client.set('user', JSON.stringify({username: 'Adeeb'}))
  }
  res.send('login');
})

app.get('/logout', (req, res) => {
  req.session.destroy();
  res.send('logout');
});

app.listen(3001, () => {
  console.log('server running on port 3001')
})

答案 1 :(得分:3)

如我的评论所述,store对象上没有本地req.session属性。 connect-redis对象继承自express-session,因此您应向req.session对象添加属性以保存状态存储,如下所示:

const session = require('express-session')
const app = require('express')()
const RedisStore = require('connect-redis')(session);

const isDev = process.env.NODE_ENV !== 'production'

app.use(session({
  store: new RedisStore({
    host: 'localhost',
    port: 6379
  }),
  secret: 'super-secret-key', // TBD: grab from env
  resave: false,
  saveUninitialized: false,
  cookie: {
    maxAge: 1000 * 60 * 60 * 24,
    secure: !isDev, // require HTTPS in production
  }
}))

app.get('/', (req, res) => {
  console.log('**testing**')
  console.log(req.session)
  console.log(req.session.id)
  res.send('rendering this text')
})

app.get('/login', (req, res) => {
  console.log(`Session ID: ${req.session.id}`)
  req.session.userId = 1
  res.redirect('/home')
})

app.get('/home', (req, res) => {
  if (req.session.userId) {
    res.send(`You are officially logged in. Your session will expire at ${req.session.cookie.expires}`)
  } else {
    res.redirect('/expired')
  }
})

app.get('/expired', (req, res) => {
  res.send('Oops. This session has expired')
})

app.listen(3001, () => {
  console.log('listening on 3001')
})

答案 2 :(得分:0)

将会话存储设为全局,在app.use(session

app.use全局变量

var store = new RedisStore({
host: 'localhost',
port: 6379
})

app.use(session({
store ,
secret: 'super-secret-key', // TBD: grab from env
resave: false,
saveUninitialized: false,
cookie: {
 maxAge: 1000 * 60 * 60 * 24,
 secure: !isDev, // require HTTPS in production
}
}))

app.use((req,res)=>{
req.session.store=store
})