1

Hi I am using nodeJs Passport npm package

I am trying to use login functionality, the code I am using is this:

let User = new mongoose.model("user", userSchema);

// use static authenticate method of model in LocalStrategy
passport.use(User.createStrategy());

// use static serialize and deserialize of model for passport session support
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

app.post("/login", function(req, res){
   const user =  new User({
       username: req.body.username,
       password: req.body.password
   });

   req.login(user, function(err){
       if(err){
           console.log(err);
           res.redirect("/login");
       }else{
           // all cookies are saved, sessions working now
           passport.authenticate("local")(req, res, function(){
            res.redirect("/secrets");
        });
       }
   });
});

But when I enters wrong password, it says UnAuthorized but it is also going to authenticate function and making the user authenticated.

May I know what is the issue in my code?

Rohan Sharma
  • 25
  • 1
  • 6

3 Answers3

1

I had the same issue. (Fix me if I'm wrong, but it seems very like a code from Angela Yu's course:) )

I noticed that in Passport.js docs its always using the passport.authenticate method but not the req.login(). Docs says that

Passport exposes a login() function on req (also aliased as logIn()) that can be used to establish a login session.

And that the login() function is used inside the passport.authenticate to create session.

So I think whats going on is the code:

  1. You enter wrong password on login page
  2. req.login() creates a session cookies as if that was true user, i.e. it logs you in (since err object in login()'s callback is not for authentication errors, but for some other purposes)
  3. then , since err object in login() callback is not for authentication errors and stays undefined , passport.authenticate(...) is called and it gives you 401 error "Unauthorized" because the password was wrong..

But the cookie for you is already has been created by the login(). So you can access all the secret stuff after that.

so the code that works for me was just:

app.post("/login", passport.authenticate("local"), (req, res) => {
    res.redirect("/secrets");
});
Nez Nez
  • 33
  • 5
1

The issue is actually from Dr. Angela's code. This is what I used to fix it:

app.post("/login", function(req, res) {
      passport.authenticate("local", {
          failureRedirect: "/loginfail"
        }
        (req, res, function() {
          res.redirect("/secrets")
        })
      })

failureRedirect is an option of passport.authenticate. You can place the custom message codes you want to display if the login fails in that route.

Michael M.
  • 10,486
  • 9
  • 18
  • 34
0

I have gone through the same issue. The below code worked for me. Took help from this post: difference between 'done' and 'next' in node.js callbacks

app.post("/login", function(req, res){

    const user= new User({
        username: req.body.username,
        password: req.body.password
    })
    passport.authenticate('local', function(err, user, info) {

        if(err) { res.redirect('/login'); }
        if(user){
            req.logIn(user, function(err) {
                if (err) { res.redirect('/login'); }
                else res.redirect('/secrets');
            });
        }
        else{ 
            //Incorrect credentials, hence redirect to login 
            return res.redirect('/login'); 
        }
        
    })(req, res);
});
Kaushik
  • 1
  • 1