使用 passport.js 管理 express.js 中不同类型用户的身份验证

Manage authentication of different types of users in express.js using passport.js

我在 Express.js 4.x 中使用 Passport.js 管理不同类型用户的状态时遇到问题 4.x。

我的 mongodb 数据库中有 3 种用户集合

1. Member (has his own profile page)
2. Operator (has his own dashboard)
3. Admin (handles the backend)

我已经创建了他们单独的 Login/Registration 系统。但似乎只有成员在工作,而其他人则没有。我什至为每个用户编写了不同的 login/registration 策略集。 喜欢成员 passport.use('signup') 和 passport.use('login')。 对于运算符 passport.use('op-signup') 和 passport.use('op-login') 等等。 我认为我没有使用正确的方法来处理用户,这意味着集合不需要分开,而是基于单个集合中的角色。对吗?

这是我目前拥有的猫鼬模型;

// Member Schema
var MemberSchema = new Schema({
   username: String,
   password: String,
   name: { first: String, last: String },
   locality: String,
   // and other attributes
});
module.exports = mongoose.model('Member', MemberSchema);

// OperatorSchema
var OperatorSchema = new Schema({
   username: String,
   password: String,
   name: { first: String, last: String },
   officeAddress: String,
   privatePhone: Number,
   // and other attributes related to the operator
});
module.exports = mongoose.model('Operator', OperatorSchema);

上面的做法是正确的还是这样的?

var UserSchema = new Schema({
   username: String,
   password: String,
   roles: {
       member: { type: Schema.Types.ObjectId, ref: 'Member' },
       operator: { type: Schema.Types.ObjectId, ref: 'Operator' },
       admin: { type: Schema.Types.ObjectId, ref: 'Admin' }
   }
});
module.exports = mongoose.model('User', UserSchema);

// and then plug the sub models to this parent one

// Member Schema
var MemberSchema = new Schema({
   _user: { type: Schema.Types.ObjectId, ref: 'User' },
   name: { first: String, last: String },
   locality: String,
   // and other attributes
});
module.exports = mongoose.model('Member', MemberSchema);

// OperatorSchema
var OperatorSchema = new Schema({
   _user: { type: Schema.Types.ObjectId, ref: 'User' },
   name: { first: String, last: String },
   officeAddress: String,
   privatePhone: Number,
   // and other attributes related to the operator
});
module.exports = mongoose.model('Operator', OperatorSchema);

我这里很迷茫,卡住了,因为登录后在session中管理用户状态时,用户对象暴露给请求对象,所以一次只能处理一种类型的用户时间,并且可能是会员,操作员和管理员不能从同一个浏览器同时登录。

那么如何在浏览器中将所有这些用户作为不同的实例进行管理呢? 我是 Node.js 的新手,来自 PHP 管理用户状态轻而易举的背景:)

我会做的是添加插件,因为你在重复用户名和密码字段,这是非常多余的

models/plugins/member.js

module.exports = function(schema) {
  schema.add({
      // All the appropriate fields that your member schema need
      role: String,

   });

}

models/user.js

var member = require(./plugins/member);

var UserSchema = mongoose.Schema({
     username: String,
     password: String
});

UserSchema.plugins(member);

以后想查看哪个用户可以访问哪个路由时,使用中间件进行查看

在您的护照配置中创建这个

exports.requireRole = function(role) {
    return function(req, res, next) {
      if (req.user && req.user.role === role) next();
      else
          res.send(404);
    }
}

稍后在您的路线中

app.get('/profile', requireRole('member'), function(req, res) {
  // do whatever you want to do
});

app.get('/dashbord', requireRole('operator'), function(req, res) {
  // do whatever you want to do
});

有很多方法可以为用户实现不同的访问级别。此方法是众多方法中的一种。

最好的解决方案是使用模式继承。这就是我们使用像 mongoose 这样的 ORM 的原因。

var VehicleSchema = mongoose.Schema({ 
  make : String,
}, { collection : 'vehicles', discriminatorKey : '_type' });

var CarSchema = VehicleSchema.extend({
  year : Number
});
var BusSchema = VehicleSchema.extend({
  route : Number
})

var Vehicle = mongoose.model('vehicle', VehicleSchema),
    Car = mongoose.model('car', CarSchema),
    Bus = mongoose.model('bus', BusSchema);

var accord = new Car({ 
  make : 'Honda',
  year : 1999
});
var muni = new Bus({
  make : 'Neoplan',
  route : 33
});

accord.save(function(err) {
  muni.save(function(err) {
    // vehicles are saved with the _type key set to 'car' and 'bus'
  });
})

此时 MongoDB 您将拥有与此类似的文档

{ "_type" : "car", "make" : "Honda", "year" : 1999, "_id" : ObjectId("5024460368368a3007000002"), "__v" : 0 }
{ "_type" : "bus", "make" : "Neoplan", "route" : 33, "_id" : ObjectId("5024460368368a3007000003"), "__v" : 0 }
Source

查询时

Vehicle.find({}, function(err, vehicles) {
  console.log(vehicles[0]); // vehicles[0] instanceof Car === true
  console.log(vehicles[1]); // vehicles[1] instanceof Bus === true
});

通过查看 briankircho 小备忘单查看源代码/更多示例 enter link description here