Mongodb-使用JWT和#x2B的用户、角色和组;RESTAPI
简介 我正在用JWT令牌为auth实现简单的MEAN应用程序。此应用允许您创建帐户,然后创建自己的组或加入现有组。每个组都有组管理员分配给每个用户的特定角色。这是我的模式,希望能帮助您更好地理解我的解决方案 用户模式Mongodb-使用JWT和#x2B的用户、角色和组;RESTAPI,mongodb,rest,database-design,jwt,mean-stack,Mongodb,Rest,Database Design,Jwt,Mean Stack,简介 我正在用JWT令牌为auth实现简单的MEAN应用程序。此应用允许您创建帐户,然后创建自己的组或加入现有组。每个组都有组管理员分配给每个用户的特定角色。这是我的模式,希望能帮助您更好地理解我的解决方案 用户模式 _id: { type: String, default: function () { return new mongo.ObjectId().toString() } }, email: { type: String, required: true, uniq
_id: {
type: String,
default: function () { return new mongo.ObjectId().toString() }
},
email: {
type: String,
required: true,
unique: true
},
displayName: {
type: String
},
hash: {
required: true,
type: String
}
_id: {
type: String,
default: function () { return new mongo.ObjectId().toString() }
},
groupName: String,
ownerUser: {
type: String,
ref: 'User'
},
userList: [
{
user: {
type: String,
ref: 'User'
},
role: {
type: String,
ref: 'Role'
}
}
]
_id: {
type: String,
default: function () { return new mongo.ObjectId().toString() }
},
groupId: String,
roleName: String,
access: [{
path: String,
allowed: Boolean
}]
组架构
_id: {
type: String,
default: function () { return new mongo.ObjectId().toString() }
},
email: {
type: String,
required: true,
unique: true
},
displayName: {
type: String
},
hash: {
required: true,
type: String
}
_id: {
type: String,
default: function () { return new mongo.ObjectId().toString() }
},
groupName: String,
ownerUser: {
type: String,
ref: 'User'
},
userList: [
{
user: {
type: String,
ref: 'User'
},
role: {
type: String,
ref: 'Role'
}
}
]
_id: {
type: String,
default: function () { return new mongo.ObjectId().toString() }
},
groupId: String,
roleName: String,
access: [{
path: String,
allowed: Boolean
}]
角色模式
_id: {
type: String,
default: function () { return new mongo.ObjectId().toString() }
},
email: {
type: String,
required: true,
unique: true
},
displayName: {
type: String
},
hash: {
required: true,
type: String
}
_id: {
type: String,
default: function () { return new mongo.ObjectId().toString() }
},
groupName: String,
ownerUser: {
type: String,
ref: 'User'
},
userList: [
{
user: {
type: String,
ref: 'User'
},
role: {
type: String,
ref: 'Role'
}
}
]
_id: {
type: String,
default: function () { return new mongo.ObjectId().toString() }
},
groupId: String,
roleName: String,
access: [{
path: String,
allowed: Boolean
}]
它的工作原理
用户注册/登录->创建组或加入现有组->组管理员将角色分配给用户
- 组将有大约250个用户
- 组可以有多个角色(10-15)
- 用户可以加入多个组
router.get('/restricted', JWTAuth, userProject, userRole, (res, req, next) => {
res.send("ok")
})
access.js
export const JWTAuth = passportAuth('jwt', {session: false});
export const userProject = async (req, res, next) => {
const userProject = await GroupModel.findOne({ _id: req.body.groupId, "userList.user" : req.user._id })
if(userProject) {
req.project = userProject;
next()
}else{
res.sendStatus(401);
}
}
export const userRole = async (req, res, next) => {
const roleId = arrayFindByObjectValue(req.user._id, 'user', req.project.userList).role;
const userRole = await RoleModel.findOne({ _id: roleId })
req.role = userRole;
next();
}
export const arrayFindByObjectValue = (value, key, array) => {
for (var i = 0; i < array.length; i++) {
if (array[i][key] === value) {
return array[i];
}
}
}
和聚合(提高15%)
问题
现在我希望你能理解我的处境。使用这种方法,我必须执行多个db查询,以便仅为简单请求获取用户角色。我担心速度。使用角色中间件(1000个组用户),每个请求需要大约150 ms的时间。我认为这个解决方案会不必要地使服务器过载。有更好的解决办法吗?我应该使用一些会话(无状态JWT..)或其他方法来临时存储用户角色吗?这种方法有更好的数据库设计吗
我读了很多关于基于角色的系统的文章,但是我从来没有遇到过这个特定的解决方案。谢谢你的回答。如果你需要更多的信息,请让我知道,我会编辑我的答案