Mahtab Alam
Mahtab Alam

Reputation: 1870

How to expose session variables to express views

I'm trying to access session variables in EJS views, but facing lots of problems.

To access the req.session locally I'm using middleware as described here Accessing Express.js req or session from Jade template

var express = require('express');
var mongoose = require('mongoose');
var db = require('./models/db.js');

var routes = require('./routes/route.js');
var user = require('./routes/user.js');
var story = require('./routes/story.js');
var bodyParser = require('body-parser');

var session = require('express-session');
var cookieParser = require('cookie-parser');

mongoose.connect('mongodb://localhost/test');

var app = express();


app.use(function(req,res,next){
    res.locals.session = req.session;
    next();
});



app.set('view engine','ejs');

app.use(express.static(__dirname + '/public'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:false}));
app.use(cookieParser());
app.use(session({secret:"qazwsxedcrfvtgbyhnujm"}));


app.get('/',routes.home);

app.get('/register',routes.register);
app.post('/newUser',user.doCreate);

app.get('/login',routes.login);
app.post('/authenticate',user.login);

app.get('/new-story',routes.newStory);
app.post('/add-story',story.addStory);


app.get('/stories/:story',story.getStory);
app.post('/stories/:slug/saveComment',story.saveComment);

var port = process.env.PORT || 3000;

var server=app.listen(port,function(req,res){
    console.log("Catch the action at http://localhost:"+port);
});

Here is the route.js for handling home route

var mongoose = require( 'mongoose' );
var Story = mongoose.model( 'Story' );
exports.home=function(req,res){
             Story.find({}, function(err,stories){
                  res.render('home',{stories:stories});
              });
}

In the home.ejs I am checking whether user is logged in or note by checking whether username property is set or not.

<% if( typeof(session.username) !== 'undefined' ) {%
<h1>Welcome</h1><%=session.username%>
<%}%>

But, on accessing the main page I get error saying Cannot read property 'username' of undefined error

I am setting the username in session once is user is authenticated.

exports.login=function(req,res){
    var email=req.body.email;
    var password=req.body.password;

    User.findOne({email:email}, function(err,user){

      if(err){
        res.redirect("/login");
      }

     user.comparePassword(password,function(err,isMatch){
       if(isMatch && isMatch==true){
         console.log("Authentication Sucessfull");
         req.session.username=user.username;
         console.log("Got USer : "+req.session.username);
         res.redirect("/");
       }else{
         console.log("Authentication UnSucessfull");
         res.redirect("/login");
       }

     });

    });
  }

Upvotes: 0

Views: 2370

Answers (1)

robertklep
robertklep

Reputation: 203554

Express runs middleware in order of their declaration.

You have this:

app.use(function(req,res,next){
    res.locals.session = req.session;
    next();
});
...
app.use(session({secret:"qazwsxedcrfvtgbyhnujm"}));

Your middleware runs before the session middleware (it's declared before it), so you create res.locals.session before the session middleware gets a chance to create req.session.

Try moving your middleware to after the session middleware:

app.use(session({secret:"qazwsxedcrfvtgbyhnujm"}));
app.use(function(req,res,next){
    res.locals.session = req.session;
    next();
});

Upvotes: 1

Related Questions