我在使用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背景,管理用户状态变得轻而易举:)
答案 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