3

I am trying to follow the Office 365 Graph API tutorial here.

However I keep running into the below error after I sign-in.

Error: Failed to serialize user into session
    at pass (C:\Users\SODS\devzone\src\nodejs\o365-graph\graph-tutorial\node_modules\passport\lib\authenticator.js:271:19)
    at serialized (C:\Users\SODS\devzone\src\nodejs\o365-graph\graph-tutorial\node_modules\passport\lib\authenticator.js:276:7)
    at passport.serializeUser (C:\Users\SODS\devzone\src\nodejs\o365-graph\graph-tutorial\app.js:20:3)
    at pass (C:\Users\SODS\devzone\src\nodejs\o365-graph\graph-tutorial\node_modules\passport\lib\authenticator.js:284:9)
    at Authenticator.serializeUser (C:\Users\SODS\devzone\src\nodejs\o365-graph\graph-tutorial\node_modules\passport\lib\authenticator.js:289:5)
    at IncomingMessage.req.login.req.logIn (C:\Users\SODS\devzone\src\nodejs\o365-graph\graph-tutorial\node_modules\passport\lib\http\request.js:50:29)
    at Strategy.strategy.success (C:\Users\SODS\devzone\src\nodejs\o365-graph\graph-tutorial\node_modules\passport\lib\middleware\authenticate.js:235:13)
    at verified (C:\Users\SODS\devzone\src\nodejs\o365-graph\graph-tutorial\node_modules\passport-azure-ad\lib\oidcstrategy.js:98:21)
    at Strategy.signInComplete [as _verify] (C:\Users\SODS\devzone\src\nodejs\o365-graph\graph-tutorial\app.js:63:10)
    at process._tickCallback (internal/process/next_tick.js:68:7)

The serializeUser method looks like below:

//Configure passport
//In-memory storage of users 
let users = {};
//Call serializeUser and deserializeUser to manage users
passport.serializeUser((user, done) => {
  //Use the OID prop of the user as the key
  users[user.profile.oid] = user;
  done(null, user.profile.oid);
}); 

passport.deserializeUser((id, done) => {
  done(null, users[id]);
});

The problem might be that user.profile.oid seems to be undefined inside the callback function of serializeUser (tried also replacing arrow functions with normal ones but didn't work either).

But the oid is being set during the sign-in and I can see it when I trace the values in the code below.

//Callback when the sign-in is complete and an access token has been obtained
async function signInComplete(iss, sub, profile, accessToken, refreshToken, params, done) {
  console.log('iss profile oid -->' + profile.oid);
  if (!profile.oid) {
    return done(new Error("No OID found in user profile."), null);
  }

  try {
    const user = await graph.getUserDetails(accessToken);

    if (user) {
      //Add properties to profile
      profile['email'] = user.mail ? user.mail : user.userPrincipalName;
    }
  } catch(err) {
    done(err, null);
  } 

  //Create simple oauth token from raw tokens
  let oauthToken = oauth2.accessToken.create(params);

  //Save the profile and token in users storage
  users[profile.oid] = {profile: oauthToken};
  return done(null, users[profile.oid]); 
}

Which is the call for the OIDCStratergy.

//Configure OIDC stratergy
passport.use(new OIDCStaregy(
  {
    identityMetadata: `${process.env.OAUTH_AUTHORITY}${process.env.OAUTH_ID_METADATA}`,
    clientID: process.env.OAUTH_APP_ID,
    responseType: 'code id_token',
    responseMode: 'form_post',
    redirectUrl: process.env.OAUTH_REDIRECT_URI,
    allowHttpForRedirectUrl: true,
    clientSecret: process.env.OAUTH_APP_PASSWORD,
    validateIssuer: false,
    passReqToCallback:  false,
    scope: process.env.OAUTH_SCOPES.split(' ')
  },
  signInComplete
));

So the question is is the undefined users.profile.oid the issue here? If so where & why does it get lost?

Soumik Das
  • 276
  • 2
  • 14

0 Answers0