Sanka Darshana
Sanka Darshana

Reputation: 1421

Configuring Local Strategy in Passport.js

I'm a bit new to Node.js and below is my problem.

I have a code like this,

passport.authenticate('local', function (error, user, info) {
    console.log("authentication happening");
    console.log(info);
    if (error) {
        return res.send(error);
    }
    else if (!user) {
        return res.send("User not found");
    }
    else {
        req.logIn(user, function (error) {
            if (error) {
                return res.send(error);
            }
            else {
                return res.json(
                    {
                        id: user
                    });
            }
        });
    }
    return false;
})(req, res, next); 

// if I remove this last set of params it doesn't give an error what does it do? Still it doesn't send the response even after I remove this.

And my strategy setting code is as follows,

passport.use(new LocalStrategy(function (username, password, done) {
    userManager.findOne(username, function (err, user) {
        if (err) {
            return done(err);
        }
        if (!user) {
            return done(null, false, {
                message: 'Incorrect username.'
            });
        }
        userManager.isValidPassword(username, password, function (error, result){
            if (result === true) {
                return done(null, user, {
                    message: 'success'
                });
            }
            else {
                return done(null, false, {
                    message: 'Incorrect password.'
                });
            }
        });
        return done("error", false, {
            message: 'Error'
        });
    });
}));

But when I run this it gives an error as following,

D:\Education\Projects\Social\social\Dev\server\NodeProject\node_modules\mongodb\lib\mongodb\connection\base.js:242
         throw message;
               ^
TypeError: object is not a function
     at D:\Education\Projects\Social\social\Dev\server\NodeProject\node_modules\mongodb\lib\mongodb\collection\query.js:147:5
     at Cursor.nextObject (D:\Education\Projects\Social\social\Dev\server\NodeProject\node_modules\mongodb\lib\mongodb\cursor.js:733:5)
     at commandHandler (D:\Education\Projects\Social\social\Dev\server\NodeProject\node_modules\mongodb\lib\mongodb\cursor.js:713:14)
     at D:\Education\Projects\Social\social\Dev\server\NodeProject\node_modules\mongodb\lib\mongodb\db.js:1806:9
     at Server.Base._callHandler (D:\Education\Projects\Social\social\Dev\server\NodeProject\node_modules\mongodb\lib\mongodb\connection\base.js:442:41)
     at D:\Education\Projects\Social\social\Dev\server\NodeProject\node_modules\mongodb\lib\mongodb\connection\server.js:485:18
     at MongoReply.parseBody (D:\Education\Projects\Social\social\Dev\server\NodeProject\node_modules\mongodb\lib\mongodb\responses\mongo_reply.js:68:5)
     at null.<anonymous> (D:\Education\Projects\Social\social\Dev\server\NodeProject\node_modules\mongodb\lib\mongodb\connection\server.js:443:20)
     at EventEmitter.emit (events.js:95:17)
     at null.<anonymous> (D:\Education\Projects\Social\social\Dev\server\NodeProject\node_modules\mongodb\lib\mongodb\connection\connection_pool.js:191:13)

Upvotes: 1

Views: 7776

Answers (1)

Grant Li
Grant Li

Reputation: 973

Your passport.authenticate looks weird.

Here is the code we have in our working copy:

app.post('/login', 
    passport.authenticate('local', { failureRedirect: failRedirect, failureFlash: false }),
            function(req, res) {
                log.info(req.user.username+' is successfully logged in.');
                log.info(JSON.stringify(req.user));
                res.redirect(successRedirect);
            });

passport.authenticate does not have a 2nd parameter as callback. Instead, it returns true or false to allow redirects to happen. So, if the login was successful, the authenticate call will return true, the next function will be called and res.redirect(successRedirect) will happen. Otherwise, failRedirect will be sent to user and redirect user to a failure to login page.

Here is our code for the strategy:

passport.use(new LocalStrategy(function(username,password,done){
        log.info(username+"//"+password+" is trying to login as local.");
        var userModel = mongoose.model('users',userSchema);
        userModel.findOne({'username':username})
            .exec(function(err,puser){
                if(err){log.info(err.stack);}
                if(!puser){
                    log.info("user not found.");
                    return done(null, false, { message: 'Unknown user ' + username });
                }
                if (password!==puser.password) {
                    log.info("password invalid.");
                    return done(null, false, { message: 'Invalid password' });
                }
                return done(null, puser);
        });
    }));

Your strategy for this part looks ok.


Edit:

Your reply now explains to me why you are seeing the error.

app.get('/login', function(req, res, next) {
    passport.authenticate('local', function(err, user, info) {
        if (err) { return next(err); }
        if (!user) { return res.redirect('/login'); }
            req.logIn(user, function(err) {
        if (err) { return next(err); }
            return res.redirect('/users/' + user.username);
        });
    })(req, res, next);
});

compare to your code:

passport.authenticate('local', function (error, user, info)
{
    ...implementation
})(req, res, next);

are very different.

function(req,res,next){(passport.authentication)(req,res,next)} must be called within app.get('path',method). In this context, there are 3 parameters being supplied from express.get call. Therefore, req,res,next actually can perform the way shown in the example. If you take (passport.authentication)(req,res,next) outside, req,res,next will not be populated. Your code would fail.

Upvotes: 4

Related Questions