1

This authenticate works fine

app.post('/login', passport.authenticate('local-login', {
    successRedirect: '/home',
    failureRedirect: '/login',
    failureFlash: true
  })
);

but I'm trying to validate the fields of the form before the authentication using express-validator.

I came with that

app.post('/login', function(req, res){
  req.checkBody('email', 'Email is required').notEmpty();
  req.checkBody('email', 'Email is not valid').isEmail();
  req.checkBody('password', 'Password is required').notEmpty();
  var validationErr = req.validationErrors();

  if (validationErr){
    res.render('login', {
      errors: validationErr,
      failureFlash: true
    });
  } else {
    // authenticate once fields have been validated
    passport.authenticate('local-login', {
        successRedirect: '/home',
        failureRedirect: '/login',
        failureFlash: true // allow flash messages
    })
  }
});

Using this second code, nothing happens when I submit the form and the client gives the error message localhost didn't send any data after a while. The first part works fine, I can see all the errors when I submit an empty form and the authenticate method is reached. I suspect this question might partially answer mine or is kind of related, but I can't understand it.

The passport.js documentation provides an example with a function but the function gets called only when the authentication is successful, so after. I'd like to perform the field validation before the authentication.

Let me know if you need the passport.authenticate code.

afkqs
  • 25
  • 1
  • 6

2 Answers2

6

passport.authenticate is a function. In your first (working) code, you're calling it as middleware, where it gets passed objects for (req, res, next) as parameters.

With your second code, you're trying to call it directly and without parameters, and the client is timing out because it's not getting a response.

If I'm not missing something, you may be able to make this work by passing (req, res) to it, like this:

  if (validationErr){
      res.render('login', {
          errors: validationErr,
          failureFlash: true
      });
  } else {
      // authenticate once fields have been validated
      passport.authenticate('local-login', {
          successRedirect: '/home',
          failureRedirect: '/login',
          failureFlash: true // allow flash messages
      })(req, res, next);
  }
Jim B.
  • 4,512
  • 3
  • 25
  • 53
  • As pointed in Jim’s answer the key here is the final (req,req,next) since passport.authenticate is a middleware, you need to call the req,res,next) and pass back a res for the function – Pari Baker Nov 12 '18 at 01:42
0

I had exactly the same code and issue whilst trying to introduce express-validator.

I can confirm that adding the additional "(req, res, next);" to the end of the passport.authenticate function does allow the authentication process to complete and /login to process.

However there seems to be no additional user added to the database after passport has authenticated with this method alone. I think a custom callback for passport is required e.g.:

http://www.passportjs.org/docs/authenticate/

Example of use: https://gist.github.com/Xeoncross/bae6f2c5be40bf0c6993089d4de2175e

SamG
  • 1
  • 2