Skip to main content

政策

¥Policies

策略是在每个请求到达 controller 之前对每个请求执行特定逻辑的函数。它们主要用于保护业务逻辑。

¥Policies are functions that execute specific logic on each request before it reaches the controller. They are mostly used for securing business logic.

Strapi 项目的每个 route 都可以与一系列策略相关联。例如,名为 is-admin 的策略可以检查请求是否由管理员用户发送,并限制对关键路由的访问。

¥Each route of a Strapi project can be associated to an array of policies. For example, a policy named is-admin could check that the request is sent by an admin user, and restrict access to critical routes.

策略可以是全局的,也可以是有范围的。全局政策 可以与项目中的任何路由关联。范围策略仅适用于特定的 APIplugin

¥Policies can be global or scoped. Global policies can be associated to any route in the project. Scoped policies only apply to a specific API or plugin.

Simplified Strapi backend diagram with routes and policies highlighted
The diagram represents a simplified version of how a request travels through the Strapi back end, with policies and routes highlighted. The backend customization introduction page includes a complete, interactive diagram.

执行

¥Implementation

可以实现一项新政策:

¥A new policy can be implemented:

  • 交互式 CLI 命令 strapi generate

    ¥with the interactive CLI command strapi generate

  • 或通过在适当的文件夹中手动创建 JavaScript 文件(参见 项目结构):

    ¥or manually by creating a JavaScript file in the appropriate folder (see project structure):

    • ./src/policies/ 全局政策

      ¥./src/policies/ for global policies

    • API 政策的 ./src/api/[api-name]/policies/

      ¥./src/api/[api-name]/policies/ for API policies

    • ./src/plugins/[plugin-name]/policies/ 用于插件策略

      ¥./src/plugins/[plugin-name]/policies/ for plugin policies


全局政策实现示例:

¥Global policy implementation example:

./src/policies/is-authenticated.js

module.exports = (policyContext, config, { strapi }) => {
if (policyContext.state.user) { // if a session is open
// go to next policy or reach the controller's action
return true;
}

return false; // If you return nothing, Strapi considers you didn't want to block the request and will let it pass
};

policyContextcontroller 上下文的封装器。它添加了一些可用于实现 REST 和 GraphQL 策略的逻辑。

¥policyContext is a wrapper around the controller context. It adds some logic that can be useful to implement a policy for both REST and GraphQL.


可以使用 config 对象配置策略:

¥Policies can be configured using a config object:

.src/api/[api-name]/policies/my-policy.js

module.exports = (policyContext, config, { strapi }) => {
if (policyContext.state.user.role.code === config.role) { // if user's role is the same as the one described in configuration
return true;
}

return false; // If you return nothing, Strapi considers you didn't want to block the request and will let it pass
};

用法

¥Usage

要将策略应用于路由,请将它们添加到其配置对象中(请参阅 路由文档)。

¥To apply policies to a route, add them to its configuration object (see routes documentation).

策略根据其范围有不同的调用方式:

¥Policies are called different ways depending on their scope:

提示

要列出所有可用策略,请运行 yarn strapi policies:list

¥To list all the available policies, run yarn strapi policies:list.

全局政策

¥Global policies

全局策略可以与项目中的任何路由关联。

¥Global policies can be associated to any route in a project.

./src/api/restaurant/routes/custom-restaurant.js

module.exports = {
routes: [
{
method: 'GET',
path: '/restaurants',
handler: 'Restaurant.find',
config: {
/**
Before executing the find action in the Restaurant.js controller,
we call the global 'is-authenticated' policy,
found at ./src/policies/is-authenticated.js.
*/
policies: ['global::is-authenticated']
}
}
]
}

插件政策

¥Plugin policies

插件 可以向应用添加和公开策略。例如,用户和权限插件 附带策略来确保用户经过身份验证或有权执行操作:

¥Plugins can add and expose policies to an application. For example, the Users & Permissions plugin comes with policies to ensure that the user is authenticated or has the rights to perform an action:

./src/api/restaurant/routes/custom-restaurant.js

module.exports = {
routes: [
{
method: 'GET',
path: '/restaurants',
handler: 'Restaurant.find',
config: {
/**
The `isAuthenticated` policy prodived with the `users-permissions` plugin
is executed before the `find` action in the `Restaurant.js` controller.
*/
policies: ['plugin::users-permissions.isAuthenticated']
}
}
]
}

API 政策

¥API policies

API 策略与声明它们的 API 中定义的路由相关联。

¥API policies are associated to the routes defined in the API where they have been declared.

./src/api/restaurant/policies/is-admin.js.

module.exports = async (policyContext, config, { strapi }) => {
if (policyContext.state.user.role.name === 'Administrator') {
// Go to next policy or will reach the controller's action.
return true;
}

return false;
};
./src/api/restaurant/routes/custom-restaurant.js

module.exports = {
routes: [
{
method: 'GET',
path: '/restaurants',
handler: 'Restaurant.find',
config: {
/**
The `is-admin` policy found at `./src/api/restaurant/policies/is-admin.js`
is executed before the `find` action in the `Restaurant.js` controller.
*/
policies: ['is-admin']
}
}
]
}


要在另一个 API 中使用策略,请使用以下语法引用它:api::[apiName].[policyName]

¥To use a policy in another API, reference it with the following syntax: api::[apiName].[policyName]:

./src/api/category/routes/custom-category.js

module.exports = {
routes: [
{
method: 'GET',
path: '/categories',
handler: 'Category.find',
config: {
/**
The `is-admin` policy found at `./src/api/restaurant/policies/is-admin.js`
is executed before the `find` action in the `Restaurant.js` controller.
*/
policies: ['api::restaurant.is-admin']
}
}
]
}