15

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?

Sunil Garg
  • 14,608
  • 25
  • 132
  • 189
Lukas Olsen
  • 5,294
  • 7
  • 22
  • 28

5 Answers5

25

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

Priya Ranjan Singh
  • 1,567
  • 1
  • 15
  • 29
AnduA
  • 610
  • 1
  • 6
  • 10
  • i have this already i my code - but i need to access the cookie on client side, using javascript - is this possible? – Lukas Olsen Sep 04 '12 at 08:23
  • 1
    I'm sorry, I didn't understand that from your question. I just analyzed the cookies in my node.js app and I don't see one set by passportjs. Connect just sets a cookie with the sessionId. The rest of the data is stored on the server. I believe you should manually set a cookie with the desired data and then parse it using javascript on the client. (using express: [link](http://expressjs.com/api.html#res.cookie) ). – AnduA Sep 04 '12 at 09:41
  • 2
    i've solved the problem myself setting a own cookie already but thanks for your info! – Lukas Olsen Sep 04 '12 at 10:08
  • This will set the userid in the session not in the cookie. – viji Jan 02 '16 at 04:00
  • This is very useful – Rishav Apr 04 '19 at 11:56
  • 2
    Does not answer the question and now future readers get confused. Looks like the poster solved by himself. – Kal Sep 18 '20 at 23:52
19

Add to signin path

res.cookie('userid', user.id, { maxAge: 2592000000 });  // Expires in one month

Add to signout path

res.clearCookie('userid');
user1071182
  • 1,609
  • 3
  • 20
  • 28
  • 3
    I think, the question is how to integrate this with passport as in the passport callbacks and in the strategy, we may not have access to req/res. – viji Jan 02 '16 at 04:01
  • Where should I add this code? I mean from where should I set cookies? – MD SHAYON Feb 09 '21 at 23:29
4

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:

  1. Add the shown handler to the authXXX/callback route, not the authXXX route.
  2. Call 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)
  3. If you have a "sign out" route, add the handler above to that route as well.
Venryx
  • 15,624
  • 10
  • 70
  • 96
0

If you're using the angular-fullstackgenerator, 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();
}
Tom Söderlund
  • 4,743
  • 4
  • 45
  • 67
-1

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();
});
Ally Haire
  • 2,398
  • 1
  • 14
  • 19