Search code examples
node.jsexpresspassport.jscloudantexpress-session

session store with cloudant connect results in req.user is not found in passport local strategy?


I created a express application with cloudant as my DB. I use passport as a authentication middleware. so By default it will provide in-memory session store. so every time i restart application, session destroys.

So I have to use some session storage mechanism like connect-cloudant.

in app.js when myaccount route is activated at that time i am not getting req.user or req.isAuthenticated() ? if i remove connect-cloudant code and try with default in memory session store, I am able to get req.uesr and req.isAuthenticated

app.js

var https         = require("https");
var fs            = require("fs");
var express       = require("express");
var app           = express();
var cookieParser  = require("cookie-parser");
var session       = require("express-session");
var CloudantStore = require('connect-cloudant')(session);
var passport      = require("passport");
var strategy      = require("passport-local").Strategy;
var path          = require("path");
var bodyParser    = require("body-parser");
var cons          = require('consolidate');
var config        = require("./config");
var Cloudant_ip   = config.CLOUDENT_IP;
var Cloudant      = require('cloudant');
var cloudant      = Cloudant(Cloudant_ip);
var Port          = config.PORT;
var Local_ip      = config.LOCAL_IP;

var cloudantStore = new CloudantStore({
    url: Cloudant_ip,
    databaseName: "sessions"
});

app.use(express.static("public/_attachments"));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());

app.use(session({
    store: cloudantStore,
  secret: 'cloudant',
  cookie: {maxAge:24*60*60*1000}
}));

require("./src/config/passport")(app);

function ensureAuthenticated(req, res, next) {
  if (req.isAuthenticated()) {
   return next();
  } else {
    res.redirect("/");
  } 
}

app.engine('html', cons.swig);
app.set('views', path.join(__dirname, 'pages'));
app.set('view engine', 'html');

app.get("/",ensureLoginAuthenticated,function(req,res) {
    res.render("index.html");
});

app.get("/myaccount",ensureAuthenticated,function(req,res) {
    res.render("my-account.html");
});

https.createServer({
  key: fs.readFileSync('key.pem'),
  cert: fs.readFileSync('cert.pem')
}, app).listen(Port,Local_ip, function() {
    console.log("server is running on port "+Port);
});

passport.js

var passport = require("passport"),
        LocalStrategy = require("passport-local").Strategy,
        Cloudant = require("cloudant"),
        cloudant = Cloudant("https://username:password@username.cloudant.com"),
        db = cloudant.db.use("myuserdatabase");

module.exports = function(app) {
    app.use(passport.initialize());
    app.use(passport.session());

    passport.serializeUser(function(user,cb) {
        cb(null,user);
    });

    passport.deserializeUser(function(user,cb) {
        cb(null, user);
    });

    passport.use(new LocalStrategy({
        usernameField: "username",
        passwordField: "password"
    },
    function(username, password, cb) {
        db.get("org.couchdb.user:"+username, function(err,body){
            if(!err) {
                if(password == body.password) {
                    var user = {
                        username: body.email,
                        password:body.password
                    };
                    cb(null, user);
                }else {
                    cb(null, false);
                }
            }else {
                cb(null, false);
            }
        });
    }));
};

I guess i am missing something here so can anyone help.


Solution

  • after messing for a day i am able to resolve this. with the use of sessionstore-cloudant, i am able to store session to cloudant.

    few things to remember

    1. cradle is required when u r using sessionstore.
    2. provide port name while connecting to cloudant.

      app.use(session({ secret:"secretword", store:sessionstore.createSessionStore({ type: 'couchdb', host: cloudanturl, port: 443, dbName: sessionDataBaseName, options: { auth: { username: cloudantUsername, password: cloudantPassword } } })
      }));