I'm using Passport.js to achieve login to my Node-App. But in my app, I need to get access to the user's ID and currently, I don't have an idea how to achieve this thing!
How can I access the user-id or should I send it in a cookie myself?
I'm using Passport.js to achieve login to my Node-App. But in my app, I need to get access to the user's ID and currently, I don't have an idea how to achieve this thing!
How can I access the user-id or should I send it in a cookie myself?
You should introduce the following code in your app, next to the configuration of the strategies:
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(obj, done) {
done(null, obj);
});
In this way, when you invoke the done
function with the authenticated user, passport takes care of storing the userId in a cookie.
Whenever you want to access the userId you can find it in the request body. (in express req["user"]
).
You can also develop the serializeUser
function if you want to store other data in the session. I do it this way:
passport.serializeUser(function(user, done) {
done(null, {
id: user["id"],
userName: user["userName"],
email: user["email"]
});
});
You can find more here: http://passportjs.org/docs/configure
Add to signin path
res.cookie('userid', user.id, { maxAge: 2592000000 }); // Expires in one month
Add to signout path
res.clearCookie('userid');
The answer by user1071182 is correct, but doesn't make clear where to place the cookie-setting code.
Here is a fuller example:
app.get("/auth/google/callback",
passport.authenticate("google"),
setUserIDResponseCookie,
(req, res, next)=>{
// if success
if (req.user) {
res.redirect("http://localhost:3000");
} else {
res.redirect("http://localhost:3000/login-failed");
}
next();
});
function setUserIDResponseCookie(req, res, next) {
// if user-id cookie is out of date, update it
if (req.user?.id != req.cookies["myapp-userid"]) {
// if user successfully signed in, store user-id in cookie
if (req.user) {
res.cookie("myapp-userid", req.user.id, {
// expire in year 9999 (from: https://stackoverflow.com/a/28289961)
expires: new Date(253402300000000),
httpOnly: false, // allows JS code to access it
});
} else {
res.clearCookie("myapp-userid");
}
}
next();
}
Note: Make sure to:
authXXX/callback
route, not the authXXX
route.passport.authenticate
"plainly", ie. without the redirect options. If you set the redirect options there, the cookies will not be set properly (from what I remember). Instead, add custom redirect code after the cookies have been set. (as shown above)If you're using the angular-fullstack
generator, this is how I modified setUserCookie
to get the _id
in the user cookie (which I later can retrieve in AngularJS).
setUserCookie: function(req, res, next) {
if (req.user) {
req.user.userInfo['_id'] = req.user._id;
console.log('Cookie', req.user.userInfo);
// Splice in _id in cookie
var userObjWithID = {
"provider": req.user.userInfo.provider,
"role": req.user.userInfo.role,
"name": req.user.userInfo.name,
"_id": req.user._id
};
res.cookie('user', JSON.stringify(userObjWithID));
}
next();
}
Alternatively you could do the following:
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
app.use((req, res, next) => {
res.locals.login = req.isAuthenticated();
res.locals.thisUser = req.user;
next();
});