Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Express flash messages with passport doesn't work

Folloing the sample https://scotch.io/tutorials/easy-node-authentication-setup-and-local I have create a simply signup app to test passport.

I'm using Express 4 and connect-flash module.

My routes are as follow, that is on GET /signup I show the signup form with any possible signupMessage flash message (always undefined). On POST /signup I try to authenticate credentials:

router.get('/signup', function(req, res) {
  debug('GET signup flash message "%s"',req.flash('signupMessage'));
  res.render('signup',  { message: req.flash('signupMessage') });
});

// process the signup form
router.post('/signup', passport.authenticate('local-signup', {
  successRedirect : '/profile', // redirect to the secure profile section
  failureRedirect : '/signup', // redirect back to the signup page if there is an error
  failureFlash : true // allow flash messages
}));

My passport related code is place next. It works but the lines like return done(null, false, req.flash('signupMessage', 'That email is already taken.')); seems that must set the request flash message seems not work because the flash message is never shown in the signup form shown by the GET method.

passport.use('local-signup', new LocalStrategy({
    // by default, local strategy uses username and password, we will override with email
    usernameField : 'email',
    passwordField : 'password',
    passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) {

    debug("Auth");

    // asynchronous
    // User.findOne wont fire unless data is sent back
    process.nextTick(function() {

    debug("before findOne");

      // find a user whose email is the same as the forms email
      // we are checking to see if the user trying to login already exists
      User.findOne({ 'local.email' :  email }, function(err, user) {

        debug("inside findOne");

          // if there are any errors, return the error
          if (err) {
            return done(err);
          }

          // check to see if theres already a user with that email
          if (user) {
            debug('user exists');
            return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
          } else {

            debug('creating new user');

            // if there is no user with that email
            // create the user
            var newUser            = new User();

            // set the user's local credentials
            newUser.local.email    = email;
            newUser.local.password = newUser.generateHash(password);

            // save the user
            newUser.save(function(err) {
              if (err) {
                throw err;
              }
              return done(null, newUser);
            });
          }

      });    

    });

}));

After looking for help I also try to put:

return done(null, false, {message: 'That email is already taken.'});

and in the GET /signup method use:

router.get('/signup', function(req, res) {
  res.render('signup',  { message: req.flash('error') });
});

but that doesn't works.

Anybody can help me?

Thanks.

like image 276
acanimal Avatar asked Mar 27 '15 21:03

acanimal


People also ask

How do I use flash on my passport?

Note: Using flash messages requires a req. Use of connect-flash middleware is recommended to provide this functionality when using Express 3. x. So you need to install connect-flash express middleware as it is recommended. var flash = require('connect-flash'); var app = express(); app.

What does Passport do in Express?

Passport is authentication middleware for Node. js. Extremely flexible and modular, Passport can be unobtrusively dropped in to any Express-based web application. A comprehensive set of strategies support authentication using a username and password, Facebook, Twitter, and more.

How do I use Express Flash?

The express-flash module exposes getter and setter methods for a flash message of the form, { flash: { type: 'type', message: 'message' }} and depends on the express-session module. The method req. flash(type, message) sets the value of a new flash message and adds it to an array of messages of the same type.

What is Passport Express JS?

Passport is Express-compatible authentication middleware for Node. js. Passport's sole purpose is to authenticate requests, which it does through an extensible set of plugins known as strategies.


2 Answers

For anyone that can have a similar problem I found my error was in sessions configuration.

As docs indicates, if you set secure cookie option, your connection must be over HTTPS or cookie will not be created. That was the reason neither normal and flash messages doesn't work.

like image 166
acanimal Avatar answered Oct 01 '22 08:10

acanimal


var session = require('express-session');
var flash = require('express-flash');
var cookieParser = require('cookie-parser');
app.use(cookieParser());
app.use(session({
    secret: config.sessionKey,
    resave: true,
    saveUninitialized: true,
}));
app.use(flash());
like image 22
p4cm4n972 Avatar answered Oct 01 '22 10:10

p4cm4n972