Node.js use passport with LocalStrategy in Authentication Part 5

Establish a session with custom callback of passport.authenticate()

         In post part 2, we have provide custom callback function into passport.authenticate() function. As the description of authenticate() function stated, we have to establish a session by ourself. This post demonstrate to establish a session. 

        We modify the code(v1.2) in part 2. First, import and setup session.

import express from "express";
import bodyParser from "body-parser";
import passport from "passport";
import {Strategy} from "passport-local";
import session from "express-session";


const app = express();

const PORT = 6000;

app.use(bodyParser.urlencoded({extends:false}));
app.use(bodyParser.json());
 
app.use(session({
secret: 'you should keep this in secret',
resave: false,
saveUninitialized: false,
}));

app.use(passport.authenticate('session'));

        Second, assign the argument user to a property user of an object and pass this object of req.session[passport] inside the body of custom callback. We imitate what the default manner of passport done to save user data into Session. Then we check the content of req.session and req.isAuthenticate() in the GET /secrets route.

app.post(
"/login", function(req, res, next){
passport.authenticate(
"local",
{
// successRedirect: "/secrets",
// failureRedirect: "/login",
session:true
},
function(err, user, info, status){
if(err){
return res.send(err);
//return res.redirect("/login");
}
if(!user){
return res.send(info);
//return res.redirect("/login");
}
//return res.send(user);
console.log("inside authenticate callback");
console.log(req.session);
req.session["passport"] = {user:user};

return res.redirect("/secrets");

}
)(req, res, next);
}
);

app.get("/secrets", (req, res) =>{
console.log("inside /secrets");
console.log(req.isAuthenticated());
console.log(req.session);
return res.send("This is secrets page. Access this page after login");
});

 Now we test with Postman. It received error message "Fail to deserialize user out of session". Same error message also printed on the terminal. 

Then we add the passport.deserializeUser() method at the end of file.


passport.deserializeUser(function(user, cb) {
process.nextTick(function() {
return cb(null, user);
});
});

We use Postman to test again. Now it get /secrets message. The terminal of server shows the content of req.session before we assign user to it and after redirect to "/secrets". We also note that the result of req.isAuthenticated() is true. Therefore, we now can use req.isAuthenticated() to restrict client access like part 3.

Postman invoke POST /login and receive secrets page message

 For additional test, if we change the property name assigned to req.session["passport"], the result of req.isAuthenticated() becomes false.

req.session["passport"] = {usered:user};

return res.redirect("/secrets");

terminal message on server

         We change back the property name assigned to req.session["passport"]. The next thing is to pass the user information stored in session to req.user when the client access the api service. We add a line console.log(req.user) inside GET /secrets route to see the content.

app.get("/secrets", (req, res) =>{
console.log("inside /secrets");
console.log(req.isAuthenticated());
console.log(req.session);
console.log(req.user);
return res.send("This is secrets page. Access this page after login");
});

         Use postman to login and we see there is user information in req.user. Passport has retrieved the content of user in Session and passed it to req.user automatically as default manner.

terminal message on server

        By assigning the user information to Session in the format of Passport default way in our custom callback function, Passport will operate normally as using the default manner of default callback. The code(v2.4) used in this post is uploaded to 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