Search code examples
javascriptnode.jsexpresspassport.js

How to display Passport.js failure messages to the user


I'm trying to setup a Local Strategy and use failureMessages display authentication errors to the user but I'm unsure the correct way to do this.

The failureMessages are added to the req.session.messages each time a failure occurs but the session.messages are never cleared. Here is the result:

enter image description here

Obviously, the last message is the most recent, but how do I know if the messages are from a current failure or a one that occurred in the past because I only want to display an error message if it is a current failure.

auth.js

  passport.use(new LocalStrategy(
    function(username, password, done) {      
      myDatabase.findOne({ username: username }, function(err, user) {
        if (err) { return done(err); }
        if (!user) { return done(null, false, { message: 'Incorrect username or password.' }); }
        if (!bcrypt.compareSync(password, user.password)) { 
          return done(null, false, { message: 'Incorrect username or password.' }); 
        }
        return done(null, user);
      });
    }
  ));

routes.js

  app.route('/login').post(passport.authenticate('local', { failureRedirect: '/', failureMessage: true }), 
    (req, res) => {
      res.redirect('/profile');
    });

server.js

app.use(session({
  secret: process.env.SESSION_SECRET,
  resave: true,
  saveUninitialized: true,
  cookie: { secure: false },
  key: 'express.sid',
  store: store
}));

app.use(passport.initialize());
app.use(passport.session());

Solution

  • I was able to clear the req.session.messages before sending a new failureMessage by setting the passReqToCallback option. This way we know that any message contained in req.session.messages is a new failure.

      passport.use(new LocalStrategy({ passReqToCallback: true },
        function(req, username, password, done) {      
          myDatabase.findOne({ username: username }, function(err, user) {
            if (err) { return done(err); }
            if (!user) { 
              req.session.messages = [];
              return done(null, false, { message: 'Incorrect username or password.' }); }
            if (!bcrypt.compareSync(password, user.password)) { 
              return done(null, false, { message: 'Incorrect username or password.' }); 
            }
            return done(null, user);
          });
        }
      ));