如何为基于角色的访问控制 (RBAC) 创建自定义条件
¥How to create custom conditions for Role-Based Access Control (RBAC)
基于角色的访问控制 (RBAC) 是一种限制某些用户访问的方法。在 Strapi 应用中,管理面板的用户是管理员。他们的角色和权限是 在管理面板中配置。
¥Role-Based Access Control (RBAC) is an approach to restricting access to some users. In a Strapi application, users of the admin panel are administrators. Their roles and permissions are configured in the admin panel.
声明新条件
¥Declaring new conditions
将单个条件声明为对象,将多个条件声明为对象数组。每个条件对象可以有 5 个可能的属性:
¥Declare a single condition as an object, and multiple conditions as an array of objects. Each condition object can have 5 possible properties:
displayName
(字符串):管理面板中显示的条件名称,¥
displayName
(string): the condition name as shown in the admin panel,name
(字符串):条件名称,烤肉串格式,¥
name
(string): the condition name, kebab-cased,category
(字符串,可选):条件可分为可用类别 在管理面板中;如果未定义,则条件将出现在 "默认" 类别下,¥
category
(string, optional): conditions can be grouped into categories available in the admin panel; if undefined, the condition will appear under the "Default" category,plugin
(字符串,可选):如果条件是由插件创建的,则应该是插件的名称,短横线格式(例如content-manager
),¥
plugin
(string, optional): if the condition is created by a plugin, should be the plugin's name, kebab-cased (e.gcontent-manager
),handler
:用于验证条件的函数(参见 使用条件处理程序)¥
handler
: a function used to verify the condition (see using the condition handler)
在 ./src/index.js
中找到的全局 bootstrap
功能 中声明并注册条件(参见 注册条件)。
¥Declare and register conditions in the global bootstrap
function found in ./src/index.js
(see Registering conditions).
条件 name
属性充当其命名空间内的唯一 ID,如果定义了 plugin
属性,则为插件,或者根命名空间。
¥The condition name
property acts as a unique id within its namespace, that is either the plugin if the plugin
property is defined, or the root namespace.
使用条件处理程序
¥Using the condition handler
条件可以应用于任何权限,条件 handler
用于验证条件。handler
是一个返回查询对象或布尔值的函数。
¥A condition can be applied to any permission, and the condition handler
is used to verify the condition. The handler
is a function returning a query object or a boolean value.
查询对象可用于验证你读取、创建、更新、删除或发布的实体的条件。他们使用 sift.js 库,但仅支持以下运算符:
¥Query objects are useful to verify conditions on the entities you read, create, update, delete or publish. They use the sift.js library, but only with the following supported operators:
$or
$and
$eq
$eqi
$ne
$in
$nin
$lt
$lte
$gt
$gte
$exists
$elemMatch
条件 handler
可以是同步或异步函数:
¥The condition handler
can be a synchronous or asynchronous function that:
接收发出请求的经过身份验证的用户,
¥receives the authenticated user making the request,
并返回
true
、false
或查询对象。¥and returns
true
,false
, or a query object.
返回 true
或 false
对于验证外部条件或经过身份验证的用户的条件很有用。例如,仅当服务器时间为下午 5 点时才允许访问管理面板中的页面的条件可以使用此处理程序:
¥Returning true
or false
is useful to verify an external condition or a condition on the authenticated user.
For instance, a condition that allows access to a page in the admin panel only if server time is 5pm could use this handler:
handler: () => new Date().getHours() === 17;
handler
函数接收经过身份验证的用户,因此它可以验证用户的条件:
¥The handler
function receives the authenticated user, so it can verify conditions on the user:
const condition = {
displayName: 'Email address from strapi.io',
name: 'email-strapi-dot-io',
async handler(user) {
return user.email.includes('@strapi.io');
},
};
为了更精细的控制,handler
函数还可以返回一个查询对象:
¥For more granular control, the handler
function can also return a query object:
const condition = {
displayName: 'price greater than 50',
name: 'price-gt-50',
async handler(user) {
return { price: { $gt: 50 } };
},
};
注册条件
¥Registering conditions
要在管理面板中可用,应在 ./src/index
中找到的全局 bootstrap
功能 中声明和注册条件。使用 conditionProvider.register()
方法注册单个条件:
¥To be available in the admin panel, conditions should be declared and registered in the global bootstrap
function found in ./src/index
. Register a single condition with the conditionProvider.register()
method:
- JavaScript
- TypeScript
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 } },
});
};
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()
:
¥To register multiple conditions, defined as an array of condition objects, use conditionProvider.registerMany()
:
- JavaScript
- 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');
},
}
];
module.exports = {
async bootstrap(/*{ strapi }*/) {
// do your boostrap
await strapi.admin.services.permission.conditionProvider.registerMany(conditions);
},
};
// path: ./src/index.ts
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);
};