如何为基于角色的访问控制(RBAC)创建自定义条件
页面摘要: 在 Strapi 中使用
conditionProviderAPI 创建自定义的基于角色的访问控制(RBAC)条件,以基于用户属性、实体查询或外部条件限制管理面板的访问。
基于角色的访问控制(RBAC)是一种将访问限制为部分用户的方法。在 Strapi 应用中,管理面板的用户是管理员。他们的角色和权限在管理面板中配置。
声明新条件
将单个条件声明为一个对象,将多个条件声明为一个对象数组。每个条件对象可以有 5 个可能的属性:
displayName(字符串):在管理面板中显示的条件名称,name(字符串):条件名称,kebab-case 形式 ,category(字符串,可选):条件可以分组到管理面板中可用的类别;如果未定义,该条件将出现在 "Default" 类别下,plugin(字符串,可选):如果条件由插件创建,应为插件的名称,kebab-case 形式(例如content-manager),handler:用于验证条件的函数(参见使用条件处理器)
在位于 /src/index.js 的全局 bootstrap 函数 中声明并注册条件(参见注册条件)。
条件 name 属性在其命名空间内充当唯一 id,命名空间要么是插件(如果定义了 plugin 属性),要么是根命名空间。
使用条件处理器
条件可以应用于任何权限,条件 handler 用于验证该条件。handler 是一个返回查询对象或布尔值的函数。
查询对象对于验证你读取、创建、更新、删除或发布的实体上的条件很有用。它们使用 sift.js 库,但仅使用以下受支持的运算符:
$or$and$eq$ne$in$nin$lt$lte$gt$gte$exists$elemMatch
此列表是穷尽的。条件查询对象在管理员创建、更新、删除或发布实体时通过 sift.js 在内存中进行评估,并且仅注册了上面列出的运算符。其他运算符,包括 REST API 和 Query Engine API 中可用的过滤运算符,例如 $eqi、$contains、$startsWith 或 $null,在此不受支持,并且在评估条件时会抛出 Unsupported operation 错误。
条件 handler 可以是同步或异步函数,它:
- 接收发出请求已通过身份验证的用户,
- 并返回
true、false或查询对象。
返回 true 或 false 对于验证外部条件或已身份验证用户上的条件很有用。
例如,一个仅在服务器时间为下午 5 点时允许访问管理面板页面的条件可以使用此处理器:
handler: () => new Date().getHours() === 17;
handler 函数接收已身份验证的用户,因此它可以验证用户上的条件:
const condition = {
displayName: 'Email address from strapi.io',
name: 'email-strapi-dot-io',
async handler(user) {
return user.email.includes('@strapi.io');
},
};
为了更精细的控制,handler 函数也可以返回查询对象:
const condition = {
displayName: 'price greater than 50',
name: 'price-gt-50',
async handler(user) {
return { price: { $gt: 50 } };
},
};
注册条件
要在管理面板中可用,条件应在位于 /src/index 的全局 bootstrap 函数 中声明并注册。使用 conditionProvider.register() 方法注册单个条件:
JavaScript
module.exports = async () => {
await strapi.admin.services.permission.conditionProvider.register({
displayName: 'Billing amount under 10K',
name: 'billing-amount-under-10k',
plugin: 'admin',
handler: { amount: { $lt: 10000 } },
});
};
TypeScript
export default async () => {
await strapi.admin.services.permission.conditionProvider.register({
displayName: 'Billing amount under 10K',
name: 'billing-amount-under-10k',
plugin: 'admin',
handler: { amount: { $lt: 10000 } },
});
};
要注册定义为 条件对象 数组的多个条件,请使用 conditionProvider.registerMany():
JavaScript
const conditions = [
{
displayName: "Entity has same name as user",
name: "same-name-as-user",
plugin: "name of a plugin if created in a plugin",
handler: (user) => {
return { name: user.name };
},
},
{
displayName: "Email address from strapi.io",
name: "email-strapi-dot-io",
async handler(user) {
return user.email.includes('@strapi.io');
},
}
];
module.exports = {
async bootstrap(/*{ strapi }*/) {
// do your boostrap
await strapi.admin.services.permission.conditionProvider.registerMany(conditions);
},
};
TypeScript
const conditions = [
{
displayName: "Entity has same name as user",
name: "same-name-as-user",
plugin: "name of a plugin if created in a plugin"
handler: (user) => {
return { name: user.name };
},
},
{
displayName: "Email address from strapi.io",
name: "email-strapi-dot-io",
async handler(user) {
return user.email.includes('@strapi.io');
},
}
];
export default async () => {
// do your boostrap
await strapi.admin.services.permission.conditionProvider.registerMany(conditions);
};