Node.js use passport with LocalStrategy in Authentication Part 4

 Display failure message 

         From the previous post, we redirect to GET /login route when the authentication fails without telling any reason. However, we usually need to explain to the client about what's wrong. 

        That's means we need to return the addition message we stated in Strategy verify function. Beside we use custom callback to return those message in part 2. We can also get the message by Passport default manner.

passport.use(
"local",
new Strategy(
{usernameField: "username", passwordField:"password"},
function verify(username, password, cb){
try{
const userCredentials = getUserInfo(username);
if(!userCredentials)
return cb(null, false, { message:"User does not exist"});
if(password === userCredentials.password){
const userInfo = {};
userInfo.name = userCredentials.name;
userInfo.id = userCredentials.id;
return cb(null, userInfo, {message: "login sucess"});
}

return cb(null, false, {message: "incorrect password"});

}catch(err){
return cb(null, false, {message: "exception error ocurred when access database"});
}
}
)
);

         According to the description in passport website,  we add a property failureMessage: true in the 2nd argument of passport.authenticate() function. The message will add to req.session.messages. Let's try on this. We modified the code(v2.2) in part 3. Add failureMessage:true and 

app.post(
"/login",
passport.authenticate(
"local",
{
successRedirect: "/secrets",
failureRedirect: "/login",
failureMessage: true
}
)
);

retrieve req.session.messages in GET "/login" handler.

app.get("/login", (req, res) =>{

let msg;

console.log(req.session);
if(req.session.messages){
msg = req.session.messages;
}

if(msg)
return res.send(msg);

return res.send("this is login page. Don't need authentication");
});

         We submit wrong password to POST "/login" route and Postman receive message "incorrect password". 

Postman received a message "incorrect password"

         We submit again but this time with wrong username. Postman has received 2 messages. The 1st one is we got in previous trial (incorrect password). The 2nd is failure message of this trial (user does not exist);

Postman receives 2 message
If we look at the terminal in server side, req.session.messages is an array of string. The failure messages accumulates.
console.log on server side
Once we login successfully, 

the failure message will be cleared.

Then if we fail login again, req.session.messages starts to accumulates

Printing message on the terminal of server.

            If we don't want the req.session.messages accumulates, we can clear it manually after retrieved the message. Here is the modified code.

app.get("/login", (req, res) =>{

let msg;

console.log(req.session);
if(req.session.messages?.length > 0){
//msg = req.session.messages;
msg = req.session.messages[0];
//clear the messages in session. Otherwise, the messages will accumulate.
req.session.messages = [];
}

if(msg)
return res.send(msg);

return res.send("this is login page. Don't need authentication");
});

Now we submit wrong username and wrong password and look at the result.

Postman receive 1 message for 1st trial
Postman receive 1 message for 2nd trial
        Now we can see 2nd trial receive 1 message only. And the server also only store 1 message.

console message of server

        Now, we can retrieve the login failure message after redirect and get only 1 message of failure caused by that trial. The completed code(v2.3)  can be found github.

 

Can retrieve failure message even we do not store userinfo in Session

         At least, we need to import and setup Session module in order to retrieve the failure message since Passport pass the message into Session storage. We modified the code(v1.1) in post part 1 as what we does in this post. Set failureMessage:true, call req.session.messages in GET /login route.

        The Modified code(v1.3) stored in github.

 

 

 

 

 

 

 

Comments

Popular posts from this blog

Use okhttp to download file and show progress bar

Download File into app specific storage with Retrofit

Unzipp file with Zip4j library