首页 > 解决方案 > 使用 MongoDB Atlas 和 Passport.js 设置 Facebook 身份验证

问题描述

我做了很多研究来找到我的问题的答案,但我还没有发现任何东西。如果我错过了答案,请随时附上链接。

我确实找到了这个解决方案,但我不确定它如何适用于这种情况:E11000 duplicate key error index in mongodb mongoose

我正在尝试将我的 Express.js、MongoDB、Passport.js 应用程序连接到 Mongo-Atlas。我设置了 Atlas 集群并从本地主机接受新用户并使用 Google Oauth 2.0,但是,当我尝试使用 Facebook 注册或登录时,出现以下错误。

MongoError: E11000 duplicate key error collection: userDB.users index: username_1 dup key: { username: null } 

会不会跟这个有关系?

passport.serializeUser(function(user, done) {
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  User.findById(id, function(err, user) {
    done(err, user);
  });
});

它在连接到我的本地主机 MongoDB 时有效,正如我所说,我无法找到解决方案。

passport.use(new FacebookStrategy({
    clientID: process.env.FBAPPID,
    clientSecret: process.env.FBSECRET,
    callbackURL: "http://localhost:3000/auth/facebook/secrets"
  },
  function(accessToken, refreshToken, profile, cb) {
    console.log(profile);
    User.findOrCreate({ facebookId: profile.id }, function (err, user) {
      return cb(err, user);
    });
  }
));

app.get('/auth/facebook', passport.authenticate('facebook'));

app.get('/auth/facebook/secrets',
  passport.authenticate('facebook', { failureRedirect: '/login' }),
  function(req, res) {
    res.redirect('/secrets');
  });

更新

所以我找到了一些关于在MongoDB上删除索引的文档但是这并不完全清楚,所以我还找到了一篇文章Dropping Existing Indexes所以我将代码实现到我自己的 app.js 文件中。

// Dropping an Index in MongoDB
User.collection.dropIndex({name : "username_1"}, function(err, res) {
    if (err) {
        console.log('Error in dropping index!', err);
    }
});

我一直在测试之间删除数据库以查看它是否有效,但是无论我如何更改代码以尝试修复它,我都遇到了这个错误!

{ _bsontype: 'Timestamp', low_: 1, high_: 1586408833 },
  ok: 0,
  errmsg: `can't find index with key: { name: "username_1" }`,
  code: 27,
  codeName: 'IndexNotFound',
  '$clusterTime': {
    clusterTime: Timestamp { _bsontype: 'Timestamp', low_: 1, high_: 1586408833 },
    signature: { hash: [Binary], keyId: [Long] }
  },
  name: 'MongoError',
  [Symbol(mongoErrorContextSymbol)]: {}
}

然而,当我db.users.getIndexes()在连接到我的 Atlas 服务器的 Mongo Shell 中运行时。果然有!我什至尝试使用dropIndexes它,它只删除了电子邮件索引!我对此感到非常沮丧!

[
    {
        "v" : 2,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "userDB.users"
    },
    {
        "v" : 2,
        "key" : {
            "email" : 1
        },
        "name" : "email_1",
        "ns" : "userDB.users",
        "background" : true
    },
    {
        "v" : 2,
        "unique" : true,
        "key" : {
            "username" : 1
        },
        "name" : "username_1",
        "ns" : "userDB.users",
        "background" : true
    }
]

标签: node.jsmongodbmongoosepassport.jsmongodb-atlas

解决方案


您在用户名上定义了唯一索引,但您的代码没有插入用户名(可能是因为用户名没有像您期望的那样从身份验证提供程序中检索到)。这会导致多个文档在用户名字段中具有相同的值(空)。

如果您的用户应该有一个用户名,您需要调试您的代码以找出它为什么不检索用户名或将其传递给 MongoDB。如果用户名是可选的,则删除其上的唯一索引。


推荐阅读