使用 MongoDB Atlas 和 Passport.js 设置 Facebook 身份验证

Posted

技术标签:

【中文标题】使用 MongoDB Atlas 和 Passport.js 设置 Facebook 身份验证【英文标题】:Setting Up Facebook Authentication with MongoDB Atlas and Passport.js 【发布时间】:2020-07-20 08:09:48 【问题描述】:

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

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

我正在尝试将我的 Express.js、MongoDB、Passport.js 应用程序连接到 Mongo-Atlas。我有我的atlas群集设置并接受来自我的localhost的新用户,并使用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);
  );
);

它在连接到我的localhost 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文件。 p >
// 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)]: 

然而,当我在连接到我的 Atlas 服务器的 Mongo Shell 中运行 db.users.getIndexes() 时。果然有!我什至尝试使用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
    
]

【问题讨论】:

我唯一可以提出解决问题的事情是在使用Facebook创建用户时将用户名设置为“无”。这似乎不是最好的解决方案。我仍然想知道是否有更好的选择。 所以 username: "none" 实际上并没有解决任何问题。我现在不知所措! :( 【参考方案1】:
db.users.dropIndex(  "username" : 1  );

这是有效的!!!

【讨论】:

【参考方案2】:

转到您的 atlas 集群,然后打开集合,然后打开索引

然后手动删除 username_1 索引。

【讨论】:

【参考方案3】:

终于成功了!我进入 Atlas 上的索引选项卡并删除了所需的用户名索引。谢谢你的帮助@oleg 出于某种原因我在网上找不到这个解释!

更新

所以从 Mongo-Atlas 中删除索引只能暂时解决问题。我相信我想出了如何从我的代码中删除索引,但我已经从 Mongo shell 中删除了它,这似乎也解决了这个问题。所以我会提供两个命令:

const User = new mongoose.model('User', userSchema);

User.collection.indexExists( "username" : 1 , function(err, results)
  console.log(results);
  if ( results === true) 
    // Dropping an Index in MongoDB
    User.collection.dropIndex(  "username" : 1  , function(err, res) 
        if (err) 
            console.log('Error in dropping index!', err);
        
    );
   else 
    console.log("Index doesn't exisit!");
  
);

在 Mongo Shell 中,进入您的数据库并运行以下命令:

db.users.dropIndex(  "username" : 1  );

要确认,运行:

db.users.getIndexes() 

为了解决这个问题,我们进行了这么多小时的研究!希望对你有帮助!

【讨论】:

所以手动删除它只能解决问题,直到我再次运行该应用程序。我正在为我的问题添加更新,因为我找到的有关删除索引的文档对我没有帮助。【参考方案4】:

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

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

【讨论】:

所以我不明白为什么将我的 Schema 电子邮件要求设置为 false 不起作用。还有其他地方我需要检查必填字段吗?也不会将唯一字段设置为 false。我错过了什么? 并非所有创建索引的软件都会自动删除未明确提及但存在于数据库中的索引。要删除任何索引,您可以使用 MongoDB Compass 等数据库管理软件。

以上是关于使用 MongoDB Atlas 和 Passport.js 设置 Facebook 身份验证的主要内容,如果未能解决你的问题,请参考以下文章

使用区块链技术的身份管理应用,MongoDB Stitch & MongoDB Atlas

使用 MongoDB Atlas 和 Passport.js 设置 Facebook 身份验证

无法使用 Mongoose 连接到 MongoDB Atlas

无法使用 MEAN 堆栈连接到 Mongodb.atlas 集群

连接到 MongoDb Atlas 服务器时出错

使用mongo_dart连接到MongoDB Atlas