PassportJS not saving session in local strategy

1.1k Views Asked by At

I'm loosely following the tutorial here, and I'm not sure why it's not working. Logging in will work fine -- it accepts and rejects me exactly how I'd expect, it will just not save the session, so visiting any links after will say that I am not authenticated.

Vivaldi dev panel says that no cookies or sessions are saved. I have set it up to save my sessions in redis and user authentication in PostgreSQL, and both databases are connected to fine.

Here is the relevant code:

index.js:

const express = require('express');

const passport = require('passport'); 
const session = require('express-session');

const Redis = require('ioredis');
const RedisStore = require('connect-redis')(session);

const bodyParser   = require('body-parser');
const cookieParser = require('cookie-parser');

const auth      = require("./app/authenticate");
const config    = require('./config');

const app = express();

var redis_client = new Redis({
  host: config.redisStore.host,
  port: config.redisStore.port,
  lazyConnect: true
});
redis_client.connect().catch(function(err) {
  throw err;
});

app.use(cookieParser(config.redisStore.secret));
app.use(session({
  cookie : {
    maxAge: 36000000000,
    secure: true
  },
  secret: config.redisStore.secret,
  store: new RedisStore({ client: redis_client }),
  resave: false,
  saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(bodyParser.urlencoded({extended: true}));

auth.init.initPassport();
app.post('/login', passport.authenticate('local', {
  successRedirect: '/testroute',
  failureRedirect: '/'
}));

var urlencodedParser = bodyParser.urlencoded({extended: false});
app.get("/testroute", passport.authenticationMiddleware(), urlencodedParser, function(req, res) {
    res.send("You are authenticated!");
});

app.listen(8080);

/app/authenticate/init.js:

const passport      = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const scrypt        = require("scrypt");

const auth = require("./userfunctions");

const authenticationMiddleware = function() {
  return function (req, res, next) {
    if (req.isAuthenticated()) {
      return next();
    }
    res.send('ERR: You are not authenticated!');
  };
}

module.exports = {
  initPassport: function() {
    passport.serializeUser(function(user, done) {
      done(null, user);
    });

    passport.deserializeUser(function(id, done) {
      auth.getUserById(id, done);
    });

    passport.use(new LocalStrategy({
        usernameField: 'email',
        passwordField: 'pwd',
      },
      function(username, password, done) {
        auth.login(username, function(err, user) {
          if (err) {console.log(err); return done(err);}
          if (!user) {return done(null, false);}
          if (!scrypt.verifyKdfSync(user.password, password)) {return done(null, false);}
          return done(null, user);
        });
      }
    ));

    passport.authenticationMiddleware = authenticationMiddleware;
  }
};

There are a few other files in /app/authenticate, which are index.js (just adds all the other things to modules.exports) and userfunctions.js, which just includes login and signup functions. I can post these if you need.

I have also omitted the config file, which is just database credentials for PostgreSQL and redis. Finally I have excluded test.html which is served when you GET /, and is just a test HTML login and signup form.

1

There are 1 best solutions below

0
On

You can use express-session npm module to save your session value.

Below are the steps-

  1. npm install express-session
  2. In your startup JS file write below code var expressSession = require('express-session'); app.use(expressSession({secret: 'yourothersecretcode', saveUninitialized: true, resave: true}));
  3. Now you can use req.session in your code

req.session is just a json object that gets persisted by the express-session middleware, using a store of your choice e.g. Mongo or Redis.