政策
¥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.
策略可以是全局的,也可以是有范围的。全局政策 可以与项目中的任何路由关联。范围策略仅适用于特定的 API 或 plugin。
¥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.
执行
¥Implementation
可以实现一项新政策:
¥A new policy can be implemented:
-
¥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:
- 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 策略的逻辑。
¥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:
- 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
代替 全局政策¥use
global::policy-name
for global policies -
使用
api::api-name.policy-name
代替 API 政策¥use
api::api-name.policy-name
for API policies -
使用
plugin::plugin-name.policy-name
代替 插件政策¥use
plugin::plugin-name.policy-name
for plugin policies
要列出所有可用策略,请运行 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 plugin 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']
}
}
]
}