CastError:在路径“_id”处转换为 ObjectId 失败

Posted

技术标签:

【中文标题】CastError:在路径“_id”处转换为 ObjectId 失败【英文标题】:CastError: Cast to ObjectId failed at path "_id" 【发布时间】:2019-01-06 11:07:12 【问题描述】:

我知道有很多这样的问题,但从我的尝试来看,似乎没有任何效果。

应用程序的快速概述,nodejs 后端使用 365 通行证身份验证用户,然后在 ReactJS 前端中使用。

我在 udemy 上关注 Node 和 React 全栈 Web 开发课程,它一直在工作,直到我开始收到以下错误:

“转换为 ObjectId 的值失败 “00037ffe-0944-74f2-0000-000000000000@84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa” 在模型“office”的路径“_id”处“

我是 MongoDB 和 mongoose 的新手,所以我真的不知道该看什么。我认为它在我的 passport.use auth 部分中。

一旦我重建了 MongoDB 以及随之而来的一切(基本架构等),错误就会消失。 (我的意思是与新的 mongo 集合/实例完全相同的代码。)

然后我得到了 365 护照身份验证工作,但过了一段时间,同样的错误会出现。如果您需要更多 sn-ps,请告诉我,这是我目前所拥有的:

这是我的护照展望策略:

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);
          

        
      )
    );

序列化/反序列化:

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);
  );
);

我的架构:

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

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

最后是我的认证路线:

 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");
    
  );
;

我知道这不是必需的,但我宁愿现在尽可能多地付出。

如果您有修复/改进之处,请按我的方式发送。

任何帮助将不胜感激。谢谢你的时间。

【问题讨论】:

尝试将您的 id 作为 objectId 类型传递。可能是_id类型转换的问题 00037ffe-0944-74f2-0000-000000000000@84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa这不是一个有效的objectId...尝试传递正确的十六进制字符串 @AnthonyWinzlet 我添加了控制台日志以查看发生了什么,似乎 deserializeUser 中的 ID 不是 mongodb 端的 _id,它是 Outlook id。知道如何解决这个问题吗? 改用req.user.id 试试 【参考方案1】:

尝试更改以下代码

当前:

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

预期

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

我认为这应该可行

【讨论】:

我试过这个,得到以下错误:“错误:传入的参数必须是一个 12 字节的字符串或 24 个十六进制字符的字符串”。我控制台记录了 id 并从上面获取了 ID 以便通过.. 还有其他想法吗?【参考方案2】:

这为我解决了问题:

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

);

【讨论】:

以上是关于CastError:在路径“_id”处转换为 ObjectId 失败的主要内容,如果未能解决你的问题,请参考以下文章

CastError:模型“Company”的路径“_id”处的值“...”转换为 ObjectId 失败

CastError:路径“_id”处的值“”转换为 ObjectId 失败

Mongoose:CastError:在路径“_id”处为值“[object Object]”转换为 ObjectId 失败

CastError:模型“用户”的路径“_id”处的值“未定义”转换为 ObjectId 失败

CastError:模型的路径“_id”处的值“:id”转换为 ObjectId 失败

CastError:模型“customer”的路径“_id”中的值“customers”转换为 ObjectId 失败