用户与权限(Users & Permissions)

页面摘要: Users & Permissions(用户与权限)管理终端用户账户、基于 JWT 的身份验证,以及对 API 的基于角色的访问。本文档解释了如何创建角色、配置权限以及保护对内容 API 的访问。

Users & Permissions(用户与权限)功能允许管理 Strapi 项目的终端用户 💡 什么是终端用户? 终端用户是消费通过 Strapi 应用创建和管理、并显示在前端应用(例如网站、移动应用、连接设备等)上的内容的用户。与管理员不同,他们无法访问管理面板。。它提供一套基于 JSON Web Tokens(JWT)的完整身份验证流程来保护你的 API,并提供一种访问控制列表(ACL)策略,使你能够管理用户组之间的权限。

  • 套餐:免费功能
  • 角色与权限:在「角色 > 插件 - 用户与权限(Users & Permissions)」中的 CRUD 权限
  • 启用:默认启用
  • 环境:在开发(Development)和生产(Production)环境中均可用

管理面板配置

Users & Permissions(用户与权限)功能既通过管理面板设置配置,也通过代码库配置。

角色

Users & Permissions(用户与权限)功能允许创建和管理终端用户角色,以配置他们可以访问的内容。

创建新角色

路径: 用户与权限插件(Users & Permissions plugin) > 角色(Roles)

在 角色(Roles) 界面的右上角,显示一个 添加新角色(Add new role) 按钮。它允许为你的 Strapi 应用的终端用户创建新角色。

点击 添加新角色(Add new role) 按钮,重定向到角色编辑界面,在那里你可以为新的角色命名并定义其详细信息和权限(见 编辑角色)。

终端用户角色界面

NOTE

默认分配给所有新终端用户的终端用户角色,可以在 用户与权限插件(Users & Permissions plugin) 的 高级设置(Advanced settings) 子节中定义(见 高级设置)。

编辑角色

路径: 用户与权限插件(Users & Permissions plugin) > 角色(Roles)

角色(Roles) 界面显示你的 Strapi 应用为终端用户创建的所有角色。

默认情况下,任何 Strapi 应用都定义了 2 个终端用户角色:

  • 已认证(Authenticated):仅当终端用户登录到前端应用时才能访问内容。
  • 公开(Public):终端用户无需登录到前端应用即可访问内容。

不过,可以创建更多角色(见 创建新角色),并且所有角色都可以通过角色编辑界面进行编辑。

  1. 点击要编辑的角色的编辑按钮 。如果你是直接从创建新角色进入角色编辑界面的,请跳过此步骤。
  2. 填写 角色详情(Role details),遵循下表的说明:
角色详情说明
名称(Name)在文本框中写入角色的新名称。
描述(Description)在文本框中写入角色的描述。它应有助于管理员理解该角色授予的访问权限。
  1. 通过以下方式配置终端用户角色的 权限(Permissions):
    1. 点击要配置的权限类别的名称(例如 Application、Content-Manager、Email 等)。
    2. 勾选要为该角色授予的操作和权限的复选框。
  2. 点击 保存(Save) 按钮。
TIP

勾选操作或权限复选框时,API 的相关绑定路由会显示在界面右侧。

为终端用户配置角色

删除角色

路径: 用户与权限插件(Users & Permissions plugin) > 角色(Roles)

虽然公开(Public)角色无法删除,但其他角色可以删除。当前分配给已删除角色的用户会自动重新分配给公开(Public)角色。

  1. 点击角色记录右侧的删除按钮 。
  2. 在删除窗口中,点击 确认(Confirm) 按钮以确认删除。

提供方

路径: 用户与权限插件(Users & Permissions plugin) > 提供方(Providers)

Users & Permissions(用户与权限)功能允许启用和配置提供方(providers),使终端用户能够通过第三方提供方登录,以通过 Strapi 应用 API 访问前端应用的内容。

默认情况下,提供方列表中包含一个默认对所有启用了 Users & Permissions 的 Strapi 应用启用的「Email(邮件)」提供方。

  1. 点击提供方的编辑 按钮以启用和配置。
  2. 在提供方编辑窗口中,点击 启用(Enable) 选项的 TRUE(是) 按钮。
  3. 填写提供方的配置。每个提供方都有其自己特定的配置集(见 用户与权限提供方文档)。
  4. 点击 保存(Save) 按钮。

提供方界面

Strapi 默认未提供的其他提供方,可以通过你的 Strapi 应用代码手动添加。点击以下任意卡片以获取关于配置或创建第三方提供方的更多信息:

  • 设置提供方 — 了解用户与权限提供方如何工作,理解登录流程,并查看常见示例。
  • 创建自定义提供方 — 了解如何为用户与权限功能创建你自己的自定义提供方。
通过提供方注册时的用户名生成

当终端用户通过身份验证提供方(如 Google 或 GitHub)注册时,Strapi 会自动使用该提供方的电子邮件地址中 @ 符号之前的部分生成用户名(例如,从 joe@gmail.com 生成 joe)。

如果生成的用户名已被占用,Strapi 会追加一个随机数字以使其唯一(例如 joe1234)。现有账户的用户名不受影响。

邮件模板

路径: 用户与权限插件(Users & Permissions plugin) > 邮件模板(Email templates)

Users & Permissions(用户与权限)功能使用 2 个邮件模板——「邮件地址确认(Email address confirmation)」和「重置密码(Reset password)」,它们会发送给终端用户:

  • 如果他们的账户必须被确认才能激活,
  • 如果他们需要对 Strapi 账户重置密码。

这两个邮件模板都可以修改。

  1. 点击邮件模板的编辑 按钮以配置和编辑。
  2. 配置邮件模板: | 设置名称 | 说明 | |--------------- | ----------------------------------------------- | | 发件人名称(Shipper name) | 指明邮件发件人的名称。 | | 发件人邮箱(Shipper email) | 指明邮件发件人的电子邮件地址。 | | 回复邮箱(Response email) | (可选)指明终端用户的回复邮件将发送到的电子邮件地址。 | | 主题(Subject) | 写入邮件的主题。可以使用变量(见 邮件模板化)。 |
  3. 在「Message(消息)」文本框中编辑邮件内容。邮件模板内容为 HTML 并使用变量(见 邮件模板化)。
  4. 点击 完成(Finish) 按钮。

邮件模板界面

高级设置

路径: 用户与权限插件(Users & Permissions plugin) > 高级设置(Advanced settings)

与 Users & Permissions(用户与权限)功能相关的所有设置都从 高级设置(Advanced Settings) 界面管理,包括为终端用户选择默认角色、启用注册和邮件确认,以及选择重置密码的落地页面。

  1. 配置你选择的设置,遵循以下说明: | 设置名称 | 说明 | | ------------------------------------ | --------------------------------------------------------------| | 已认证用户的默认角色(Default role for authenticated users) | 点击下拉列表,选择新终端用户的默认角色。 | | 每个邮箱地址一个账户(One account per email address) | 点击 TRUE(是) 按钮,将具有相同电子邮件地址的终端用户账户数量限制为 1。 点击 FALSE(否) 以禁用此限制,并允许多个终端用户账户关联到同一个电子邮件地址(例如,登录 kai.doe@strapi.io 时可以通过多个不同的提供方)。 | | 启用注册(Enable sign-ups) | 点击 TRUE(是) 按钮以启用终端用户注册。 点击 FALSE(否) 以防止终端用户注册到你的前端应用。 | | 重置密码页面(Reset password page) | 指明你的前端应用的重置密码页面的 URL。 | | 启用邮件确认(Enable email confirmation) | 点击 TRUE(是) 按钮,通过发送确认邮件来启用终端用户账户确认。 点击 FALSE(否) 以禁用账户确认。 | | 重定向 URL(Redirection url) | 指明终端用户在确认其 Strapi 账户后应被重定向到的页面 URL。 |

  2. 点击 保存(Save) 按钮。

高级设置界面

基于代码的配置

虽然大多数 Users & Permissions(用户与权限)设置通过管理面板处理,但一些更具体的设置可以通过配置和自定义你的 Strapi 项目代码来进行微调。

JWT 配置

你可以使用 插件配置文件 配置 JSON Web Token(JWT)的生成。

Strapi 使用 jsonwebtoken 生成 JWT。

JWT 管理模式

Users & Permissions(用户与权限)功能支持 2 种 JWT 管理模式。

通过设置 /config/plugins 文件 中 users-permissions.config 对象的 jwtManagement 属性来定义使用哪种模式。该属性接受 legacy-support 或 refresh:

模式说明使用场景
legacy-support(默认)使用传统配置签发长效 JWT现有应用、简单身份验证
refresh使用会话管理,配合短时效访问令牌(access token)和刷新令牌(refresh token)以增强安全性新应用、增强的安全要求
(见 管理面板配置)

为了向后兼容,Users & Permissions(用户与权限)功能默认使用 legacy 模式:

module.exports = ({ env }) => ({
  'users-permissions': {
    config: {
      jwtManagement: 'legacy-support',
      jwt: {
        expiresIn: '30d', // 传统 JWT 过期时间
      },
    },
  },
});
说明
  • jwtSecret 是用于创建新 JWT 的随机字符串,通常使用 JWT_SECRET 环境变量 设置。

  • jwt.expiresIn(仅 legacy 模式)以秒数或描述时间跨度的字符串表示。

    例如:60、"45m"、"10h"、"2 days"、"7d"、"2y"。数值被解释为秒数。如果你使用字符串,务必提供时间单位(分钟、小时、天、年等),否则默认使用毫秒单位("120" 等于 "120ms")。

WARNING

出于安全考虑,不建议将 JWT 过期时间设置为超过 30 天。

当使用 refresh 模式时,配置文件如下所示:

JavaScript


module.exports = ({ env }) => ({
  // …
  'users-permissions': {
    config: {
      jwtManagement: 'refresh',
      sessions: {
        accessTokenLifespan: 600, // 10 分钟(默认)
        maxRefreshTokenLifespan: 2592000, // 30 天(默认)
        idleRefreshTokenLifespan: 1209600, // 14 天(默认)
        maxSessionLifespan: 86400, // 1 天(默认)
        idleSessionLifespan: 7200, // 2 小时(默认)
        httpOnly: false, // 设为 true 以使用 HTTP-only Cookie
        cookie: {
          name: 'strapi_up_refresh',
          sameSite: 'lax',
          path: '/',
          secure: false, // 在生产环境中为 true
        },
      },
    },
  },
  // ...
});

TypeScript


export default ({ env }) => ({
  // …
  'users-permissions': {
    config: {
      jwtManagement: 'refresh',
      sessions: {
        accessTokenLifespan: 600, // 10 分钟(默认)
        maxRefreshTokenLifespan: 2592000, // 30 天(默认)
        idleRefreshTokenLifespan: 1209600, // 14 天(默认)
        maxSessionLifespan: 86400, // 1 天(默认)
        idleSessionLifespan: 7200, // 2 小时(默认)
        httpOnly: false, // 设为 true 以使用 HTTP-only Cookie
        cookie: {
          name: 'strapi_up_refresh',
          sameSite: 'lax',
          path: '/',
          secure: false, // 在生产环境中为 true
        },
      },
    },
  },
  // ...
});

在 refresh 模式下,已认证的终端用户可以通过 REST API 列出其活动会话 以及 撤销会话。

注册配置

如果你在用户 模型(model) 模型(Models),在 Strapi 中也被称为内容类型(content-types),定义了内容结构的表示形式。 用户是任何新 Strapi 应用中内置的一种特殊内容类型。你可以像自定义其他模型一样自定义 Users 模型,例如添加更多字段。 更多信息,请参阅 模型(models) 文档。 中添加了任何需要在注册时被接受的额外字段,你需要将它们添加到 the /config/plugins file 的 config.register 对象的允许字段列表中,否则它们将不会被接受。

以下示例展示了如何确保一个名为 "nickname" 的字段在用户注册时被 API 接受:

JavaScript

module.exports = ({ env }) => ({
  // ...
  "users-permissions": {
    config: {
      register: {
        allowedFields: ["nickname"],
      },
    },
  },
  // ...
});

TypeScript

export default ({ env }) => ({
  // ...
  "users-permissions": {
    config: {
      register: {
        allowedFields: ["nickname"],
      },
    },
  },
  // ...
});

速率限制配置

速率限制应用于身份验证和注册端点,以防止滥用。可以配置以下参数来更改其行为。其他配置选项由 koa2-ratelimit 包提供:

the /config/plugins file 中提供以下选项:

参数说明类型默认值
ratelimit用于自定义身份验证和注册端点速率限制的设置object{}
ratelimit.enabled启用或禁用速率限制器booleantrue
ratelimit.interval将请求视为同一速率限制桶的时间窗口(毫秒)integer60000(1 分钟)
ratelimit.max时间窗口内允许的最大请求数integer10
ratelimit.prefixKey速率限制键的前缀string${userIdentifier}:${requestPath}:${ctx.request.ip}

JavaScript

module.exports = ({ env }) => ({
  // ... 其他插件配置 ...
  // Users & Permissions 配置
  'users-permissions': {
    config: {
      ratelimit: {
        enabled: true,
        interval: 60000, // 1 分钟
        max: 10,
      },
    },
  },
  // ...
});

TypeScript

export default ({ env }) => ({
  // ... 其他插件配置 ...
  // Users & Permissions 配置
  'users-permissions': {
    config: {
      ratelimit: {
        enabled: true,
        interval: 60000, // 1 分钟
        max: 10,
      },
    },
  },
  // ...
});

邮件模板配置 {#templating-emails}

默认情况下,此插件附带两个模板:重置密码和邮件地址确认。模板使用 Lodash 的 template() 方法 来填充变量。

你可以在管理面板的 插件(Plugins) > 角色与权限(Roles & Permissions) > 邮件模板(Email Templates) 选项卡下更新这些模板(见 配置邮件模板)。

可以使用以下变量:

重置密码

  • USER(对象)
    • username
    • email
  • TOKEN 对应于为重置密码而生成的令牌。
  • URL 是用户点击邮件中的链接后将被重定向到的地址。
  • SERVER_URL 是绝对服务器 URL(在服务器配置中配置)。

邮件地址确认

  • USER(对象)
    • username
    • email
  • CODE 对应于为确认用户邮件而生成的 CODE。
  • URL 是确认代码的 Strapi 后端 URL(默认 /auth/email-confirmation)。
  • SERVER_URL 是绝对服务器 URL(在服务器配置中配置)。

安全配置

JWT 可以被验证和信任,因为信息是经过数字签名的。要对令牌进行签名,需要一个 密钥(secret)。默认情况下,Strapi 将其作为 JWT_SECRET 环境变量存储在 .env 文件中。

如果你想使用不同的环境变量,可以更新配置文件。

JavaScript


module.exports = {
  jwtSecret: process.env.SOME_ENV_VAR,
};

TypeScript


export default {
  jwtSecret: process.env.SOME_ENV_VAR,
};

创建自定义回调验证器 {#creating-a-custom-password-validation}

默认情况下,Strapi SSO 仅重定向到与配置中的 URL 完全相等的重定向 URL:

用户与权限配置

如果你需要配置一个自定义处理程序来接受其他 URL,可以在 plugins.js 中为该 users-permissions 插件创建一个回调(callback)validate 函数。

  // ... 其他插件配置 ...
  // Users & Permissions 配置
  'users-permissions': {
    enabled: true,
    config: {
      callback: {
        validate: (cbUrl, options) => {
          // cbUrl 是 Strapi 被要求将
          // 从提供方接收到的身份验证信息重定向到的地址

          // 在此情况下,我们仅验证
          // 如果使用基础 URL,应始终包含末尾斜杠
          // 尽管在实际使用中你也应包含完整路径
          if (cbUrl.startsWith('https://myproxy.mysite.com/') || 
              cbUrl.startsWith('https://mysite.com/')) {
            return;
          }

          // 注意你必须抛出错误才能使验证失败
          // 返回值不会被检查
          throw new Error('Invalid callback url');
        },
      },
    },
  },

路由与策略自定义 {#customizing-routes-and-policies}

Users & Permissions(用户与权限)功能的路由和控制器可以通过 插件扩展系统 进行扩展和重写。这对于为用户端点添加自定义策略、重写控制器逻辑或添加新路由很有用。

使用

Users & Permissions(用户与权限)功能既可以通过管理面板使用(用于创建新的终端用户账户),也可以通过 API 使用。

管理面板使用

使用该功能的路径: 内容管理器(Content Manager)

借助 Users & Permissions(用户与权限)功能,终端用户及其账户信息作为内容类型进行管理。当 Strapi 应用安装了 Users & Permissions 时,会自动创建 3 个集合类型,其中包括唯一一个直接在内容管理器(Content Manager)中可用的「User(用户)」。

通过内容管理器管理终端用户

在带有 Users & Permissions(用户与权限)功能的前端应用中注册新终端用户,相当于向 User 集合类型添加新条目。

  1. 转到 内容管理器(Content Manager)中的 User 集合类型。
  2. 点击右上角的 创建新条目(Create new entry) 按钮。
  3. 填写条目的默认字段。你项目的管理员专门为你的 Strapi 应用添加的额外字段也可能显示。 | 字段 | 说明 | | --------- | ---------------------------- | | 用户名(Username) | 写入终端用户的用户名。 | | 电子邮件(Email) | 在文本框中写入终端用户的完整电子邮件地址。 | | 密码(Password) | (可选)在文本框中写入新密码。你可以点击 图标以显示密码。 | | 已确认(Confirmed) | (可选)点击 ON(开) 以确认终端用户账户。 | | 已阻止(Blocked) | (可选)点击 ON(开) 以阻止终端用户账户,防止他们访问内容。 | | 角色(Role) | (可选)指明应授予新终端用户的角色。如果此字段未填写,终端用户将被分配默认角色(见 高级设置 中的「默认角色(Default role)」选项)。 |
  4. 点击 保存(Save) 按钮。
NOTE

如果终端用户可以在你的前端应用自行注册(见 高级设置 中的「启用注册(Enable signups)」选项),则会自动创建一个新条目,并且该条目的字段将由终端用户指示的信息填充。不过,所有字段都可以由 Strapi 应用的管理员编辑。

API 使用

每次发送 API 请求时,服务器都会检查是否存在 Authorization 响应头,并验证发出请求的用户是否有权访问该资源。

NOTE

当你创建一个没有角色的用户,或使用 /api/auth/local/register 路由时,该用户会被赋予 authenticated(已认证)角色。

Users & Permissions(用户与权限)功能通过 REST API 和 GraphQL API 暴露身份验证、用户管理和角色/权限端点。带有请求和响应示例的完整端点参考可在专用子页面中找到:

  • REST API — 用户与权限功能的身份验证端点、用户 CRUD、角色和权限。
  • GraphQL API — 通过 GraphQL 进行身份验证变更(mutation)、用户查询和角色管理。

令牌使用

登录或注册时收到的 jwt 随后可用于发出受限权限的 API 请求。要作为用户发出 API 请求,请将 JWT 放入请求的 Authorization 响应头中,使用 Bearer 令牌模式:

import axios from 'axios';

const token = 'YOUR_TOKEN_HERE';

// 请求 API。
axios
  .get('http://localhost:1337/api/posts', {
    headers: {
      Authorization: `Bearer ${token}`,
    },
  })
  .then(response => {
    // 处理成功。
    console.log('Data: ', response.data);
  })
  .catch(error => {
    // 处理错误。
    console.log('An error occurred:', error.response);
  });

任何没有令牌的请求默认都会采用 public(公开)角色权限。在管理面板中修改每个用户角色的权限。身份验证失败返回 401 (unauthorized) 错误。

Strapi 上下文中的 User 对象

user 对象对成功通过身份验证的请求可用。

已认证的 user 对象是 ctx.state 的一个属性,如下例所示:

create: async ctx => {
  const { id } = ctx.state.user;

  const depositObj = {
    ...ctx.request.body,
    depositor: id,
  };

  const data = await strapi.services.deposit.add(depositObj);

  // 发送 201 `created`
  ctx.created(data);
};