passport: DeserializeUser is not called.

I am facing an issue in my main project. I tried to replicate the same issue in a small server project and it’s working, can’t figure out what’s wrong with the big brother, so I started fiddling with the passport’s session.js. So the difference I found out was. When from the correct code this file is called, there is a variable called su.

   var self = this, su;
   if (req._passport.session) {
   su = req._passport.session.user;
  }
  console.log(su+"su");`

So for the project it works. It gives the output 56699cf997f929f52959ddbasu But for the case where deserailzer user siltently fails It gives the answer. undefinedsu. What could possibly cause this?? In one project it’s working. Exactly same stuff. But in one it is not. Please help

And also one more unexpected behaviour undefinedsu undefinedsu undefinedsu undefinedsu It is getting printed 4 times. Why the same function will be called 4 times??

Also one more behavior. In my bad app. Everytime I login a new session is created. But in my correct app it only logs it in once. So is it somethings to do with like it is not able to get data from the database??
I am trying to list out reasons , probably someone would have face it?

About this issue

Most upvoted comments

I have the same issues. passport.deserializeUser() not getting executed and a new session id is created for each request. I have spent many hours trying to resolve this. I have read dozens of SO post dating back to 2012 and nothing I do resolves the issue. Express JS session and Passport are no where near as simple to use as the docs make it out to be. I have tried dozens of solutions from around the internet with no luck. Unfortunately I am trying to build a simple back end with node js to provide some API methods for a front end developer job interview and since I cannot make this technology work in a very simple scenario I guess I have to pass on the job opportunity.

@SarasArya Hi friend. I guess i have the same issue, My back i running in 4000 and my front in another port. How did you solve it ? remember ? thanks !!

Hey @jaredhanson came across this issue, see if you can pinpoint it in the source code. What I have observed is, whenever I make cross-origin request i.e. Let’s say my server is running on port 7000 and a request is coming from my front end which is running on port 8080. Deserialize User is never called and when I create an index.html in my node.js folder and serve from there, deserialize user is called.

Hey i had the same issue and for me it was the cookie: { maxAge: 86400000, secure: true }you need to remove the secure: true and then it should work

For every other lost soul out there, this is what was going on in my case and how I fixed it.

I have a React FE, served on: localhost:3000 and an Express BE, served on: localhost:5000

In Express I am using Passport with ‘local’ strategy and a persistent session-store (Redis). I have also configured cors, to allow sending credentials from the frontend.

app.use(cors({
   origin: 'http://localhost:3000`,
   credentials: true,
   allowedHeaders: ['Content-Type'], // this is needed for sending JSON
}));

So like everybody else here, I was having problems with Passport not deserializing users. On the frontend to successfully send back the session cookie back I did:

fetch('http://localhost:5000/private', { credentials: 'include'} );

So, I was successfully receiving the connect.sid cookie on the backend, which is used for session identification, but the user never got set. Now stupidly, because of the passport.deserialize function’s description (“Registers a function used to deserialize user objects out of the session”), I thought this is also the function which queries the session-store (in my case Redis) with the correct sessionId to retrieve the UserId, and then we query our database (in my case MongoDB) for the actual user data to be set on req.user. This, however, is not the case: passport.deserialize only does the second part: finding the user in MongoDB, only if it successfully received a UserId as a parameter from the session-store from some other function.

Now why was I receiving undefined if I had the session saved in session store (Redis) and the cookie with SID was being sent back to backend?

Well here’s the kicker, contrary to what the name suggests { credentials: 'include'} should not only be specified when you want to send back the credential cookies, BUT also when you first make the authentication request and are RECEIVING said cookies. So for it to work you need set credentials: include while both receiving and sending the cookies.

What actually happened: On successful authentication Express was sending back an authenticated cookie, but because my POST authentication request did not include credentials: 'include' option, the browser never set the cookie. On the next GET request to a ‘/private’ route, because the cookie was not set, Express sent a new default cookie. That was the cookie I was seeing that was being sent back - but I was sending the incorrect cookie.

All I needed to change was adding credentials: 'include' to POST:

fetch('http://localhost:5000/login', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify(body),
        credentials: 'include', // this is needed for browser to set the cookie it receives
    });

So in short, always use credentials: 'include' option (or with axios withCredentials: true) both when RECEIVING and setting cookies, as well as when SENDING them.

Related: #570 Source: https://stackoverflow.com/a/72614577/17239746

i ran into the same problem. I guess the route for which deserializeUser() is not called, would be using a middleware or express-router (basically you have app.use() instead of app.get() or app.post()).

The route would be something like=> app.use(‘/book’,isAuthorized,booksRouter). where isAuthorized is a middleware and booksRouter is the router.

Now the deserialiseUser function is only called on app.get() or app.post() directly.

If you want to use app.use(), add passport.initialize() middleware like this: app.use(‘/book’,passport.initialize(), isAuthorized, booksRouter)

Hope it clears your doubt!