4

I have an extremely small express app to illustrate a problem I'm having.

I'm using connect-redis as a session store on my express app. I'm having a problem simply connecting to it though. Simply printing out req.session.store results in undefined as shown below:

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')
})

The output of this is:

listening on 3001
**testing**
undefined

In the store property, I've tried connecting via the url property and the client property in addition to the current host and port method.

I'm not seeing any errors either so I'm not sure why the store is always undefined.

What am I missing with this?

also, I did start redis using redis-server and I am able to connect to it through other clients


Update 1
Also, I did look at this StackOverflow which some found useful. The issue is, from version 1.5> of express-session, it says you don't need the cookie-parser module, so I don't believe that's the issue.

qarthandso
  • 2,100
  • 2
  • 24
  • 40
  • Any reason you're expecting a `store` property? I don't see it in the documentation. From what I can see, your store is stored under the `session` property itself. Is `req.session` defined? – willascend Dec 31 '18 at 23:24

3 Answers3

7

req.session will only be having properties that are set to the session, you have never set a session property named store. below is an example code of a working RedisStore sessions

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')
})
Adeeb basheer
  • 1,422
  • 10
  • 19
3

As noted in my comment, there is no native store property on the req.session object. The connect-redis object inherits from express-session, so you should add properties to the req.session object to hold your state store as shown below:

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')
})
willascend
  • 1,503
  • 8
  • 15
0

Make the session store global, use it in the app.use(session

app.use the global variable

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
})
Sam Washington
  • 626
  • 4
  • 12