Search code examples
node.jspassport-local

passport authenticate timing out


I've just started my journey into Node.js and I'm trying to tackle the idea of making a local strategy for logging a user in.

I've been chasing my functions through and testing with Postman. Now my authenticate stratedgy is hanging and I can't get my head around why.

passport.use(new LocalStrategy(
    function(username, password, done){
        console.log(username) // <-- this doesn't log
        User.findOne({userName: username}, function(err, user){
            if(err) return done(err);
            if(!user){
                return done(null, false, {
                    message: 'Could not login with those details.'
                });
            }
            if(!user.validPassword(password)) {
                return done(null, false, {
                    message: 'Could not login with those details.'
                });
            }
            return done(null, user);
        })   
    }
))

I've made a really rudimentary post request that applies authentication.

app.post('/login', function(req, res){
    console.log(req.body)
    if(!req.body.userName || !req.body.password ) {
        res.status(400),
        res.json({"status" : "fail", "message" : "All fields 
required"});
        return;
    }

    passport.authenticate('local', function(err, User, info){
        let token;

        if(err){
            res.status(400),
            res.json({"status" : "fail", "message" : err});
            return;
        }

        if(User){
            token = User.generateJwt();
            res.status(200);
            res.json({"status" : "success", "token" : token });

        }else{
            res.status(401);
            res.json({"status" : "fail", "message" : info });
        }
    })
}) 

From what I can see the initial checks are fine with missing fields however its when it hits passport.authenticate that it hangs and doesn't even appear to fall into my defined strategy.

I've been going through the documentation and I'm sure I'm missing something here but just can't see it. If anyone can point me in the right direction I'd really appreciate it.


Solution

  • A call to passport.authenticate returns a middleware function with a signature of (req, res, next). In your example you use a custom callback feature, so you have to call this resulting function manually with relevant parameters in the handler:

    app.post('/login', function(req, res){
        console.log(req.body)
        if(!req.body.userName || !req.body.password ) {
            res.status(400),
            res.json({"status" : "fail", "message" : "All fields 
    required"});
            return;
        }
    
        passport.authenticate('local', function(err, User, info) {
            let token;
    
            if(err){
                res.status(400),
                res.json({"status" : "fail", "message" : err});
                return;
            }
    
            if (User) {
                token = User.generateJwt();
                res.status(200);
                res.json({"status" : "success", "token" : token });
    
            } else{
                res.status(401);
                res.json({"status" : "fail", "message" : info });
            }
    
        // perform an actual call
        })(req, res);
    })
    

    Also keep in mind that passport-local looks for username field by default, not userName like you have in your request's params validation.