用户权限设计及初始化
基于 strapi 版本 5.23.0 分析
strapi 的角色/权限分两套,分别是后台 Web 管理用户和系统用户


这两类角色/权限在数据库中分别有自己的表,各自维护各自的。如果做一个系统,大概率是要从 系统用户 层面去管理角色/权限的,因此本文主要是分析 系统用户 层面的角色/权限设计,以及如何通过代码初始化固定的一些角色以及对应的权限(这样就不需要后台手动创建、勾选以及后续新增接口的再次勾选)
“系统用户”的角色/权限设计

我初始化了一个项目,建立了角色 1 和角色 2,观察上图的权限表:
红框是项目初始化自带的权限
绿框和蓝框是我在管理后台给两个角色勾选的权限
重点在
api::series.series.create
,两个角色都勾选了它,但是创建了两条。由此可知:strapi 通过固定字符串来标识权限,当一个角色需要该权限时,先新建一条权限,再将这条权限关联到角色上,而不是复用之前创建的权限。
最终得到初始角色/权限的代码:
javascript
const ROLE_MAP = [
{
name: '超级管理员',
type: 'superadmin',
description: '超级管理员角色',
permissions: {
'api::order.order': ['find', 'findOne', 'update'],
'api::series.series': ['find', 'findOne', 'create', 'update'],
'api::package.package': ['find', 'findOne', 'create', 'update'],
'api::portfolio.portfolio': ['find', 'findOne', 'create', 'update', 'delete'],
},
},
{
name: '普通客户',
type: 'customer',
description: '普通客户角色',
permissions: {
'api::order.order': ['find', 'findOne'],
'api::series.series': ['find', 'findOne'],
'api::package.package': ['find', 'findOne'],
},
},
]
// 创建角色并分配权限
for (const roleConfig of ROLE_MAP) {
// 检查角色是否已存在
const findedSimpleRole = await strapi.documents('plugin::users-permissions.role').findFirst({
filters: {
type: roleConfig.type,
},
})
// 要么已存在,要么新创建,最终拿到documentId
const roleDocId = findedSimpleRole
? findedSimpleRole.documentId
: (
await strapi.documents('plugin::users-permissions.role').create({
data: {
name: roleConfig.name,
type: roleConfig.type,
description: roleConfig.description,
},
})
).documentId
const findedEndRole = await strapi.documents('plugin::users-permissions.role').findOne({
documentId: roleDocId,
populate: {
permissions: true,
},
})
const permissionDocIds = []
for (const [controller, actions] of Object.entries(roleConfig.permissions)) {
for (const action of actions) {
// 找到对应的权限
const permission = findedEndRole.permissions.find(
(p) =>
// p格式
// {
// "id": 1,
// "documentId": "bnlfd7fvb7bkk1i8svxdoclj",
// "action": "api::global.global.find",
// "createdAt": "2025-01-07T06:26:15.179Z",
// "updatedAt": "2025-01-07T06:26:15.179Z",
// "publishedAt": "2025-01-07T06:26:15.179Z",
// "locale": null
//
p.action === `${controller}.${action}`
)
if (permission) {
permissionDocIds.push(permission.documentId)
} else {
permissionDocIds.push(
(
await strapi.documents('plugin::users-permissions.permission').create({
data: {
action: `${controller}.${action}`,
},
})
).documentId
)
}
}
}
await strapi.documents('plugin::users-permissions.role').update({
documentId: roleDocId,
data: {
permissions: permissionDocIds,
},
})
}