政策
🌐 Policies
Page summary:
策略在控制器之前执行,以对路由执行授权或其他检查。本文档中的说明涵盖了生成全局或特定范围的策略以及将它们连接到路由配置中。
策略是在每个请求到达控制器之前执 行特定逻辑的函数。它们主要用于保护业务逻辑。
🌐 Policies are functions that execute specific logic on each request before it reaches the controller. They are mostly used for securing business logic.
Strapi 项目的每个路由都可以关联到一组策略。例如,一个名为 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.
策略可以是全局的或有范围的。全局策略可以关联到项目中的任何路由。有范围的策略只适用于特定的API或插件,并应存放在相应的./src/api/<api-name>/policies/或./src/plugins/<plugin-name>/policies/文件夹下。

实现
🌐 Implementation
可以实现一项新政策:
🌐 A new policy can be implemented:
- 使用 交互式 CLI 命令
strapi generate - 或者通过在相应的文件夹中创建一个 JavaScript 文件手动完成(参见 项目结构):
./src/policies/用于全球政策./src/api/[api-name]/policies/用于 API 策略./src/plugins/[plugin-name]/policies/用于插件策略
全球政策实现示例:
🌐 Global policy implementation example:
- JavaScript
- TypeScript
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
};
export default (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
};
policyContext 是 controller 上下文的一个封装。它增加了一些逻辑,这些逻辑对于在 REST 和 GraphQL 中实现策略可能很有用。
可以使用 config 对象配置策略:
🌐 Policies can be configured using a config object:
- JavaScript
- TypeScript
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
};
export default (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:
- 使用
global::policy-name用于 全局策略 - 使用
api::api-name.policy-name用于 API 政策 - 使用
plugin::plugin-name.policy-name用于 插件政策
要列出所有可用的策略,请运行 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.
- JavaScript
- TypeScript
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']
}
}
]
}
export default {
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:
- JavaScript
- TypeScript
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']
}
}
]
}
export default {
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.
- JavaScript
- TypeScript
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;
};
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']
}
}
]
}
export default (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;
};
export default {
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.ts` controller.
*/
policies: ['is-admin']
}
}
]
}
要在另一个 API 中使用策略,请使用以下语法引用它:api::[apiName].[policyName]:
🌐 To use a policy in another API, reference it with the following syntax: api::[apiName].[policyName]:
- JavaScript
- TypeScript
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']
}
}
]
}
export default {
routes: [
{
method: 'GET',
path: '/categories',
handler: 'Category.find',
config: {
/**
The `is-admin` policy found at `./src/api/restaurant/policies/is-admin.ts`
is executed before the `find` action in the `Restaurant.js` controller.
*/
policies: ['api::restaurant.is-admin']
}
}
]
}