Skip to main content

政策

¥Policies

Page summary:

Policies execute before controllers to enforce authorization or other checks on routes. Instructions in this documentation cover generating global or scoped policies and wiring them into router configs.

策略是在每个请求到达 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 feature 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']
}
}
]
}