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

时间:2015-10-27 18:23:16

标签: javascript node.js mongodb express passport.js

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

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

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

我创建了他们独立的登录/注册系统。但只有成员似乎有效,其他人则没有。我甚至为每个用户编写了不同的登录/注册策略集。 比如成员passport.use('signup')和passport.use('login')。 对于operator 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);

我在这里很困惑并处于困境中,因为在登录后在会话中管理用户状态时,用户对象会暴露给请求对象,因此它一次只能处理一种类型的用户,并且可能是成员,运营商和管理员无法从同一浏览器同时登录。

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

2 个答案:

答案 0 :(得分:1)

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

模型/插件/ member.js

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

   });

}

模型/ 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
});

有很多方法可以为用户实现不同的访问级别。这种方法很多。

答案 1 :(得分:0)

最好的解决方案是使用架构不一致。这就是为什么我们使用像猫鼬这样的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 little cheatsheet enter link description here