Undefined method flash in the view of node.js - node.js

Problem in accessing flash messages on view in node.js
In my Controller
this.req.flash('info','successfully submited');
this.redirect("/home");
In my home view I am not able to get flash messages as
req.flash('info');
EDIT
In controller
self.req.flash('message','hello');
In view
<%= req.flash('message) %>
In server.js
app.configure(function (){
app.use(express.cookieParser());
app.use(express.session({ secret:'yoursecret',cookie: { maxAge: 24 * 60 * 60 * 1000 }}));
app.use(passport.initialize());
app.use(locomotive.session());
app.use(flash());
app.use(passport.session());
app.use(app.router);
app.dynamicHelpers({ messages: require('express-messages') });
});
I have the locomotive framework.

Please see tempdata example https://github.com/MKxDev/TempData
var tempData = require('tempdata');
var app = express();
app.configure(function() {
...
// This has to appear BEFORE the router
app.use(express.cookieParser());
app.use(express.session({ secret: 'your_super_secret_session_key' })); // please change this!
app.use(tempData);
...
});
...
// Routes
app.get('/', function(req, res) {
// Retrieve tempData value here. It won't exist unless the request
// was redirected
var tempVal = JSON.stringify(req.tempData.get('test_val'));
res.render('index', { title: 'Express', temp: tempVal });
});
app.post('/', function(req, res) {
// Set tempData value here
req.tempData.set('test_val', { x: 'Hello World!' });
res.redirect('/');
});

Move your app.use(flash()) higher in the order...see below. Flash needs to be initialized before passport so that flash is recognized and available to passport.
app.configure(function (){
app.use(express.cookieParser());
app.use(express.session({ secret:'yoursecret',cookie: { maxAge: 24 * 60 * 60 * 1000 }}));
app.use(flash()); // moved this up a few lines
app.use(passport.initialize());
app.use(locomotive.session());
app.use(passport.session());
app.use(app.router);
app.dynamicHelpers({ messages: require('express-messages') });
});

Related

Why is req.session undefined when I am checking user is logged in so that I can conditionally serve static files?

Once the user logs in, I am trying to serve static files. I applied the answer found here and I am having difficulty implementing it.
Upon log-in, I have this inside of routes.js:
app.post('/', function(req, res){
AM.manualLogin(req.body['user'], req.body['pass'], function(e, o){
if (!o){
res.status(400).send(e);
} else {
req.session.user = o;
if (req.body['remember-me'] == 'true'){
res.cookie('user', o.user, { maxAge: 900000 });
res.cookie('pass', o.pass, { maxAge: 900000 });
}
console.log(req.session);
res.status(200).send(o);
}
});
});
where I am setting the user in the request's session.
Inside app.js I have:
var http = require('http');
var express = require('express');
var session = require('express-session');
var bodyParser = require('body-parser');
var errorHandler = require('errorhandler');
var cookieParser = require('cookie-parser');
var MongoStore = require('connect-mongo')(session);
var app = express();
app.locals.pretty = true;
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/app/server/views');
app.set('view engine', 'pug');
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(require('stylus').middleware({ src: __dirname + '/app/public' }));
function isLoggedIn( req, res, next ) {
console.log(req.session);
if (typeof req.session.user == undefined) {
res.redirect('/');
}
next();
}
app.use(express.static(__dirname + '/app/public'));
app.use('/home', isLoggedIn, express.static(__dirname + "/app/server/docs"));
app.use(session({
secret: 'faeb4453e5d14fe6f6d04637f78077c76c73d1b4',
proxy: true,
resave: true,
saveUninitialized: true,
store: new MongoStore({ url: process.env.DB_URL })
})
);
require('./app/server/routes')(app);
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
where I am conditionally trying to render the static files for /home.
The problem resides in isLoggedIn where req.session is always undefined even though it is defined in my router function. Why is this? My log statements show that is is being set, but somehow is lost inside isLoggedIn.
One potential problem I see is your app.use(session(...)); is placed after your app.use('/home', isLoggedIn, ...);. Hence, the session is not being properly loaded in when visiting the /home path. Try placing the app.use(session(...)); middleware before the app.use('/home', isLoggedIn, ...); middleware.
This is due the fact that the execution of middleware is determined by the order of loading (i.e. if it's higher in your code, it's executed first).

nodejs: "req.session.save is not a function" error during authentication

I am using PassportJS to authenticate users in my application. After a user logs in, the session is created, but soon after being redirected, the session appears to become undefined once again because it hasn't been saved. I found online that often times with redirects, the redirect completes before the session is saved, and so it's as if authentication never happened. The apparent solution is to use the req.session.save function so that redirects will only happen after the session is saved. However, I am getting an error log of "TypeError: req.session.save is not a function." Can somebody please help?
Here is my code for app.js.
var express = require('express'),
passport = require('passport'),
session = require('express-session'),
bodyParser = require('body-parser'),
RedisStore = require('connect-redis')(session),
redis = require('redis'),
logger = require('morgan'),
errorHandler = require('express-error-handler'),
site = require('./site'),
oauth2 = require('./oauth2'),
port = process.env.PORT || 8080;
var app = express();
var redisClient = redis.createClient(8080, 'localhost');
// use sessions for tracking logins
app.use(session({
secret: 'keyboard cat',
resave: true,
saveUninitialized: true,
store: new RedisStore({
client: redisClient,
host: "pub-redis-14280.us-central1-1-1.gce.garantiadata.com",
port: 12543,
ttl: 260
})
}));
app.use(logger('dev'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json({ type: 'application/json' }));
app.use(passport.initialize());
app.use(passport.session());
app.use(errorHandler({ dumpExceptions: true, showStack: true }));
// use ejs as file extension for views
app.set('view engine', 'ejs');
app.use(express.static(__dirname + '/views'));
// use passport
require('./auth');
// Account linking
app.get('/', site.index);
app.get('/login', site.loginForm);
app.post('/login', site.login);
app.get('/logout', site.logout);
app.get('/authorize', oauth2.authorization);
app.post('/authorize/decision', oauth2.decision);
// set up local server
if (module === require.main) {
// [START server]
// Start the server
var server = app.listen(process.env.PORT || 8080, function () {
var port = server.address().port;
console.log('App listening on port %s', port);
});
// [END server]
}
module.exports = app;
site.js:
var passport = require('passport');
var login = require('connect-ensure-login');
// get layout
exports.index = function (req, res) {
console.log("layout loaded");
res.render('layout');
}
// get login form
exports.loginForm = function (req, res) {
console.log("login page loaded");
res.render('login');
}
// post login form
exports.login = [
passport.authenticate('local'),
function (req, res) {
req.session.save(function (err) {
res.redirect('/');
});
}
]
// logout
exports.logout = function (req, res) {
req.logout();
res.redirect('/');
}
Passport serialize/deserialize user:
passport.serializeUser(function(id, done) {
console.log("serializing user");
done(null, id);
});
passport.deserializeUser(function(id, done) {
console.log("deserializing user");
done(null, id);
});
In my passport authentication, I return the user id for simplicity, since that's all I need to represent users in my system.
In case anybody else is still having this issue (like me), try following Nathan's comment above and debug your connection to your redis/mongo/etc store.
What worked for me was I had my redis host set to http://localhost so I swapped it to 127.0.0.1 (local development of course) and everything immediately worked.

node.js: connect-mongo and Remember me checkbox

I use connect-mongo to store sessions in a DaaS, then I added a Remember me checkbox in the login page but when I don't check the textbox, it still writes the sessions in the sessions table. I wonder what I can be doing wrong:
server.js:
// server.js
// set up ======================================================================
// get all the tools we need
var express = require('express');
var app = express();
var port = process.env.PORT || 5000;
var mongoose = require('mongoose');
var passport = require('passport');
var flash = require('connect-flash');
var morgan = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
var MongoStore = require('connect-mongo')(session);
var path = require('path'); //join method
var configDB = require('./config/database.js');
//pass passport for configuration
require('./config/passport')(passport);
// configuration ===============================================================
mongoose.connect(configDB.url, {useMongoClient : true}); // connect to our database
// set up our express application
app.use(express.static(path.join(__dirname, 'views'))); //angular and css files
app.use(morgan('dev')); // log every request to the console
app.use(cookieParser()); // read cookies (needed for auth)
app.use(bodyParser()); // get information from html forms
app.set('view engine', 'ejs'); // set up ejs for templating
//required for passport
app.use(session({
store: new MongoStore({ mongooseConnection: mongoose.connection, ttl: 14 * 24 * 60 * 60, autoRemove:'native', collection:'AllSessions' }),
secret: 'foo'
}));
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
// use connect-flash for flash messages stored in session
app.use(flash());
// routes ======================================================================
require('./app/routes.js')(app, passport); // load our routes and pass in our app and fully configured passport
//log all other requests here
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'views'));
});
// launch ======================================================================
app.listen(port);
console.log('The magic happens on port ' + port);
routes.js (POST code):
// process the login form
app.post('/login', passport.authenticate('local-login', {
successRedirect: '/profile', // redirect to the secure profile section
failureRedirect: '/login', // redirect back to the signup page if there is an error
failureFlash: true // allow flash messages
}),
function(req, res, next)
{
if (!req.body.remember_me)
{
return next();
}
else{
app.use(session({
store: new MongoStore({ mongooseConnection: mongoose.connection, ttl: 14 * 24 * 60 * 60, autoRemove:'native', collection:'AllSessions' }),
secret: 'foo'
}));
}
});
Any suggestions are appreciated. Thanks in advance.
You're trying to initialize session when remember me is clicked, so rather than doing that. Initialize the session with a bare-minimum timeout and then use the code below:
app.use(session({
store: new MongoStore({ mongooseConnection: mongoose.connection, ttl: 3600000, autoRemove:'native', collection:'AllSessions' }),
secret: 'foo'
}));
app.post('/login', passport.authenticate('local-login', {
successRedirect: '/profile', // redirect to the secure profile section
failureRedirect: '/login', // redirect back to the signup page if there is an error
failureFlash: true // allow flash messages
}),
function(req, res, next)
{
if (!req.body.remember_me)
{
req.session.cookie.expires = false;
return next();
}
else{
req.session.cookie.maxAge = 2628000000; // for one month.
}
});

Express js req.session always undefined

I used Express Node.js to make login page with SQL server and I want to use session. Here's my code:
/**
* Module dependencies.
*/
var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var admin = require('./routes/admin');
var http = require('http');
var path = require('path');
var bodyParser = require('body-parser');
var session = require('express-session');
var async = require("async");
var edge = require('edge');
var cookieParser = require('cookie-parser');
var app = express();
// all environments
app.set('port', process.env.PORT || 3030);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(bodyParser.urlencoded({extended:true}));
app.use(express.methodOverride());
app.use(app.router);
app.use(require('stylus').middleware(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'assets')));
app.use(express.cookieParser());
app.use(express.session({
cookieName: 'session',
secret: 'dgjdjdfjfjhhytjhd',
duration: 30 * 60 * 1000,
sctiveDuration: 50 * 60 * 1000,
cookie: { maxAge: 24 * 60 * 60 * 1000 }
}));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
///////////// Routs Here .......
app.get('/', function(req, res) {
res.send('<h5>Welcome</h5>Go To Login');
});
app.get('/login', function(req, res) {
res.render('login');
});
/*======================================= Post For Login & Redirect To Admin Page =====================================*/
app.post('/login', function (req, res) {
var username = req.body.username;
var password = req.body.password;
var params = {
connectionString: "Data Source=AHMAD-HOME;Initial Catalog=nodejs;Integrated Security=True",
source: "SELECT * FROM users WHERE username='"+ username+"' and password='"+ password+"'"
};
var getUsers = edge.func('sql', params);
getUsers(null, function (error, result) {
if (error) throw error;
if (result) {
if (result == '') {
console.log(' Empty Data From Database');
res.redirect('/login');
} else {
req.session.userid= result;
res.redirect('admin');
}
} else {
console.log('kkkkkkkkkkk');
}
});
console.log('The UserName Is ' + username + ' And The Password Is : ' + password);
});
app.get('/admin', function (req, res) {
res.render('admin');
console.log(req.session);// stack here
});
http.createServer(app).listen(app.get('port'), function () {
console.log('Express server listening on port ' + app.get('port'));
});
I always have an undefined session on admin page.
I used express-session and I tried client-session before but I still the same error.
app.use(**express.**session({
cookieName: 'session',
secret: 'dgjdjdfjfjhhytjhd',
duration: 30 * 60 * 1000,
sctiveDuration: 50 * 60 * 1000,
cookie: { maxAge: 24 * 60 * 60 * 1000 }
}));
Remove the part in **s. That has been deprecated in the newest releases of Express. You have to use the middleware express-session, which you have already set up and assigned to session.

Application works with app.all but not with app.use... not sure why

I'm having some problems trying to implement some middleware in my app.
Specicially, the app.use() does not seem to catch and I don't understand why.
Below is roughly what I have.
routes/index.js
var Sessions = require('../events');
module.exports = exports = function(app) {
app.use(Sessions.isLoggedIn);
//app.use() does not catch but this does
//app.all('*', Sessions.isLoggedIn);
// Home Page
app.get('/', displayHome);
app.get('/:library/:books', displayLibrary);
}
events.js
module.exports = exports = {
isLoggedIn: function(req, res, next) {
console.log('isLoggedIn');
return next();
}
Any suggestions as to why app.use() is not catching?
UPDATE:
Here is the configuration in ape.js
app.configure(function() {
app.set('port', process.env.VCAP_APP_PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.logger('dev'));
app.use(express.compress()); // compress responses
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(expressValidator);
app.use(express.cookieParser('locket'));
app.use(express.cookieSession({
key: 'locket',
secret: 'mySecret',
cookie: {httpOnly: true, expires: 0, path: '/'}
}));
// cache every file going out
app.use(function(req, res, next) {
if (!res.getHeader('Cache-Control')) {
res.setHeader('Cache-Control', 'public, max-age=' + (86400 / 1000));
}
next();
});
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function(){
app.use(express.errorHandler({showStack: true, dumpExceptions: true}));
});
routes(app);
The router is responding to the request before your middleware function has a chance to run.
app.js sets up several other middleware functions, then uses app.router. You then call your routes/index.js file, which uses a new middleware function which gets added after app.router.
use your isLoggedIn function before the router, or use it specifically with the routes that need to check login state:
app.get('/', Sessions.isLoggedIn, function(req, res) { ... });

Resources