2
votes

I know there are multiple questions like this but from what I have attempted nothing seems to be working.

A quick overview of the application, nodejs backend that authenticates users with 365 passport auth, this is then used in a ReactJS front end.

I was following Node with React full stack web dev course on udemy and it was working until I started to receive the following error:

"Cast to ObjectId failed for value "00037ffe-0944-74f2-0000-000000000000@84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa" at path "_id" for model "office" "

I am a novice with MongoDB and mongoose so I really don't know what to look at. I think it is somewhere in my passport.use auth section.

Once I rebuilt the MongoDB and all that goes with it (basic schema etc.) the error would go away. (And I mean literally the exact same code with new mongo collection/instance.)

I then got 365 passport authentication to work but after a while, the same error will show itself. Should you need more snippets please let me know, here is what I have so far:

Here is my passport Outlook strategy:

passport.use(
      new OutlookStrategy(
        {
          clientID: keys.OUTLOOK_CLIENT_ID,
          clientSecret: keys.OUTLOOK_SECRET,
          callbackURL: "/authorize-outlook"
        },
        async (accessToken, refreshToken, profile, done) => {
          const exist = await Office.findOne({ outlookID: profile.id }).catch(
            error => console.log("error: ", error)
          );
          if (exist) {
            return done(null, exist);
          } else {
            const user = new Office({
              outlookID: profile.id,
              displayName: profile.displayName
            }).save();
            done(null, user);
          }

        }
      )
    );

Serialize/Deserialize:

passport.serializeUser((user, done) => {
  //turns user into id
  // see mlabs _id, identifying ID added my mongo
  // this is not profile id from google
  done(null, user.id);
});

// ID into a mongoose instance
// id placed in cookie above in "serializeUser" i.e the user.id
passport.deserializeUser((id, done) => {
  //turns id into user (mongoose model instance)
  Office.findById(id).then(user => {
    done(null, user);
  });
});

My Schema:

const mongoose = require("mongoose");
const { Schema } = mongoose;

OfficeSchema = new Schema({
  outlookID: String,
  displayName: String
});
mongoose.model("office", OfficeSchema);

Finally my authentication routes:

 app.get(
    "/auth/outlook",
    passport.authenticate("windowslive", {
      scope: [
        "openid",
        "profile",
        "offline_access",
        "https://outlook.office.com/Mail.Read"
      ]
    })
  );

  //   Use passport.authenticate() as route middleware to authenticate the
  //   request.  If authentication fails, the user will be redirected back to the
  //   login page.  Otherwise, the primary route function will be called,
  //   which, in this example, will redirect the user to the home page.
  app.get(
    "/authorize-outlook",
    passport.authenticate("windowslive"),
    (req, res) => {
      res.redirect("/dashboard");
    }
  );
};

I know this is more than what is necessary but I would rather give as much as possible now.

If you have a fix/improvements please send them my way.

Any help would be greatly appreciated. Thanks for your time.

2
try passing your id as objectId type. might be issue of _id type conversionShubham Agarwal Bhewanewala
00037ffe-0944-74f2-0000-000000000000@84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa this is not a valid objectId... Try to pass the correct hexa decimal stringAshh
@AnthonyWinzlet I have added console logs to see whats happening and it seems that the ID in deserializeUser is not the _id on the mongodb side, its the outlook id. any idea how to fix that?dwalsh
Try with req.user.id insteadAshh

2 Answers

0
votes

Try changing below code

Current:

passport.deserializeUser((id, done) => {
  //turns id into user (mongoose model instance)
  Office.findById(id).then(user => {
    done(null, user);
  });
});

Expected

passport.deserializeUser((id, done) => {
  //turns id into user (mongoose model instance)
  Office.findById(mongoose.Types.ObjectId(id)).then(user => {
    done(null, user);
  });
});

I think this should work

0
votes

This fixed it for me:

passport.deserializeUser((id, done) => {
  Office.findById(id).then(user => {
    done(null, user);
  });

});