Mongodb 如何使用CASL处理ref字段(mongoose)上的条件
在将Casl用于一些简单的项目之后,我正在尝试实现一些更复杂的东西。我正在尝试与网站上描述的内容混合 对于这个基本示例,我尝试向用户主题授予读取操作权限,但仅限于组织中的用户条目: 我的用户模型Mongodb 如何使用CASL处理ref字段(mongoose)上的条件,mongodb,typescript,mongoose,casl,Mongodb,Typescript,Mongoose,Casl,在将Casl用于一些简单的项目之后,我正在尝试实现一些更复杂的东西。我正在尝试与网站上描述的内容混合 对于这个基本示例,我尝试向用户主题授予读取操作权限,但仅限于组织中的用户条目: 我的用户模型 接口用户属性{ 电子邮件:字符串; 名字:字符串; lastName:string; 密码:字符串; 角色:罗莱多克; 组织机构:OrganizationDoc; } 接口用户模型扩展了mongoose.Model{ 构建(attrs:UserAttrs):UserDoc; } 接口UserDoc扩展了
接口用户属性{
电子邮件:字符串;
名字:字符串;
lastName:string;
密码:字符串;
角色:罗莱多克;
组织机构:OrganizationDoc;
}
接口用户模型扩展了mongoose.Model{
构建(attrs:UserAttrs):UserDoc;
}
接口UserDoc扩展了mongoose.Document{
电子邮件:字符串;
名字:字符串;
lastName:string;
活动:布尔值;
密码:字符串;
createdAt:日期;
更新日期:日期;
角色:罗莱多克;
组织机构:OrganizationDoc;
}
const userSchema=new mongoose.Schema(
{
电邮:{
类型:字符串,
要求:正确,
独一无二:没错,
特里姆:没错,
匹配:[/.+\@.+\..+/,“请填写有效的电子邮件地址”],
},
名字:{
类型:字符串,
要求:正确,
特里姆:没错,
},
姓氏:{
类型:字符串,
要求:正确,
特里姆:没错,
},
活动:{
类型:布尔型,
默认值:true,
要求:正确,
},
密码:{
类型:字符串,
要求:正确,
},
创建数据:{
类型:日期,
要求:正确,
默认值:Date.now,
},
更新日期:{
类型:日期,
要求:正确,
默认值:Date.now,
},
角色:{
类型:mongoose.Schema.Types.ObjectId,
要求:正确,
ref:'角色',
},
组织:{
类型:mongoose.Schema.Types.ObjectId,
参考:“组织机构”,
},
},
{
toJSON:{
转换(_doc,ret){
ret.id=ret.\u id;
删除检索id;
删除ret.password;
删除第五节;
},
},
}
);
userSchema.pre('save',异步函数(完成){
if(this.isModified('password')){
const hashed=wait Password.toHash(this.get('Password'));
this.set('password',散列);
此.set('updatedAt',Date.now);
}
完成();
});
userSchema.statics.build=(attrs:UserAttrs)=>{
返回新用户(attrs);
};
const User=mongoose.model('User',userSchema);
导出{User};
组织模式
接口组织属性{
id:字符串;
名称:字符串;
}
接口组织模型扩展了mongoose.Model{
构建(attrs:OrganizationAttrs):OrganizationDoc;
}
导出接口OrganizationDoc扩展了mongoose.Document{
名称:字符串;
版本:编号;
}
const organizationSchema=新的mongoose.Schema(
{
姓名:{
类型:字符串,
要求:正确,
独一无二:没错,
特里姆:没错,
},
},
{
toJSON:{
转换(_doc,ret){
ret.id=ret.\u id;
删除检索id;
},
},
}
);
set('versionKey','version');
插件(updateIfCurrentPlugin);
organizationSchema.statics.findByEvent=(事件:{
id:字符串;
版本:编号;
}) => {
返回组织.findOne({
_id:event.id,
版本:event.version-1,
});
};
organizationSchema.statics.build=(attrs:OrganizationAttrs)=>{
返回新组织({
_id:attrs.id,
名称:attrs.name,
});
};
const Organization=mongoose.model(
"组织",,
组织模式
);
出口{组织};
榜样
接口角色{
名称:字符串;
权限:字符串;
组织机构:OrganizationDoc;
}
接口角色模型扩展了mongoose.Model{
建造(属性:RoleAttrs):RoleDoc;
}
导出接口RoleDoc扩展了mongoose.Document{
名称:字符串;
权限:字符串;
组织机构:OrganizationDoc;
}
const roleSchema=newmongoose.Schema(
{
姓名:{
类型:字符串,
要求:正确,
独一无二:没错,
特里姆:没错,
},
权限:{
类型:字符串,
要求:正确,
特里姆:没错,
},
组织:{
类型:mongoose.Schema.Types.ObjectId,
要求:正确,
参考:“组织机构”,
},
},
{
toJSON:{
转换(_doc,ret){
ret.id=ret.\u id;
删除检索id;
删除第五节;
},
},
}
);
roleSchema.pre('save',异步函数(完成){
完成();
});
roleSchema.statics.build=(属性:RoleAttrs)=>{
返回新角色(attrs);
};
const Role=mongoose.model('Role',roleSchema);
导出{角色};
角色的权限字段存储为字符串。一旦用户登录,我就向JWT令牌添加权限
const existingUser=wait User.findOne({email,active:true})
.populate('角色')
.填充(“组织”);
//检查用户是否有效。。。
//userPermissions=[{action:'read',subject:'User',conditions:{organization:'{{organization.id}}},},},](作为字符串)
const userPermissions=Mustache.render(
existingUser.role.permissions,
现有用户
);
log(用户权限);
//结果==>[{“操作”:“读取”,“主题”:“用户”,“条件”:{“组织”:“5F4BC6644E27664265CB033D7”}]
//Generate json web令牌JWT
常量userJWT=jwt.sign(
{
id:existingUser.id,
电子邮件:existingUser.email,
organizationId:existingUser.organization.id,
userRolePermissions:userPermissions,
},
process.env.JWT_键!
);
然后在中间件中,我创建了与
const{id,email,organizationId,userroleppermissions}=jwt.verify(
req.session.jwt,
process.env.JWT_键!
)作为象征;
const currentUser:UserPayload={
id:id,
电邮:电邮,,
organizationId:organizationId,
userRolePermissions:createAbility(JSON.parse(userRolePermissions)),
};
可创建性的结果是
i {
s: false,
v: [Object: null prototype] {},
p: [Object: null prototype] {},
g: [Object: null prototype] {
User: [Object: null prototype] {
read: [Object: null prototype] {
'0': t {
t: [Function],
i: undefined,
action: 'read',
subject: 'User',
inverted: false,
conditions: { organization: '5f4bc8d85dc07d269e4f303d' },
reason: undefined,
fields: undefined
}
}
}
},
j: [
{
action: 'read',
subject: 'User',
conditions: { organization: '5f4bc8d85dc07d269e4f303d' }
}
],
O: {
conditionsMatcher: [Function],
fieldMatcher: [Function: j],
resolveAction: [Function: u]
}
}
如果我执行
const organizationId=req.params.organi