跳至内容

Shield 概念

本文档介绍了整个库中使用的一些基本概念。

存储库状态

Shield 的设计理念是,应用程序的初始设置完全可以在代码中完成,无需在数据库中保存任何内容。这意味着您不必创建大型种子文件,这些文件需要在每个环境中运行。

相反,它可以放在版本控制之下,尽管 Settings 库允许将这些设置轻松地存储在数据库中,如果您创建了一个供用户更新这些设置的界面。

设置

Shield 使用官方 Settings 库,取代了 CodeIgniter config() 帮助器。如果您想修改 Config 类值,这提供了一种将它们保存到数据库中的方法,但如果在数据库中找不到任何内容,它会回退到标准 Config 类。

用户提供程序

Shield 有一个模型来处理用户持久性。Shield 将其称为“用户提供程序”类。CodeIgniter\Shield\Models\UserModel 类为您提供了一个默认模型。

您可以使用自己的模型来定制用户属性。有关详细信息,请参阅 定制用户提供程序

用户身份

用户帐户与识别该用户所需的信息分开存储。这些识别数据片段称为用户身份。默认情况下,该库有两种类型的身份:一种用于标准电子邮件/密码信息,另一种用于访问令牌。

将这些身份与用户帐户本身保持松散耦合,有助于与第三方登录系统、JWT 系统等进行集成——所有这些都针对单个用户。

虽然这有可能使系统变得更加复杂,但当尝试从用户实体访问时,emailpassword 字段会自动为您查找。在需要向用户显示 email 字段时,应谨慎制作查询,否则您很容易遇到一些 n+1 慢查询。

当您在 UserModelsave($user) 一个 User 实例时,电子邮件/密码身份将自动更新。如果不存在电子邮件/密码身份,则必须在调用 save() 之前将电子邮件和密码都传递给用户实例。

密码验证器

在注册用户帐户时,必须验证用户的密码,以确保其符合应用程序的安全要求。Shield 使用验证器管道来处理验证。这允许您打开或关闭适合您应用程序的任何验证系统。以下验证器可用

  • CompositionValidator 验证密码本身的组成。这过去包括确保它包含符号、数字等。根据当前的 NIST 建议,这仅对密码强制执行最小长度。您可以在 Config\Auth::$minimumPasswordLength 中定义最小长度。默认情况下启用此功能。默认最小值为 8
  • NothingPersonalValidator 将比较密码与 Config\Auth::$personalFields 中指定的任何字段,例如名字或姓氏等。此外,它还将与用户名的一些简单变体进行比较。如果给定的密码与任何个人信息过于相似,它将被拒绝。相似性值在 Config\Auth::$maxSimilarity 中定义。默认值为 50,但有关更多详细信息,请参阅配置文件中的文档块。默认情况下启用此功能。
  • DictionaryValidator 将比较密码与提供的文件,其中包含大约 600,000 个常见密码,这些密码在过去几年中已在各种数据转储中看到。如果所选密码与文件中找到的任何密码匹配,它将被拒绝。默认情况下启用此功能。
  • PwnedValidator 类似于 DictionaryValidator。它不与本地文件进行比较,而是使用第三方网站 Have I Been Pwned 来检查来自网络上许多数据转储的超过 6.3 亿个泄露密码的列表。搜索是安全进行的,并提供比简单字典版本更多信息。但是,这确实需要对第三方进行 API 调用,并非每个应用程序都能接受。您应该使用此验证器或 DictionaryValidator,而不是同时使用两者。默认情况下禁用此功能。

您可以在 Config\Auth::$passwordValidators 中选择要使用的验证器

public array $passwordValidators = [
    CompositionValidator::class,
    NothingPersonalValidator::class,
    DictionaryValidator::class,
    // PwnedValidator::class,
];

您可以对密码验证使用上面说明的 strong_password 规则。

注意

strong_password 规则仅支持检查用户自己的密码的用例。如果访问者已通过身份验证,它会为 NothingPersonalValidator 获取已通过身份验证的用户的 data。如果您想要设置和检查其他用户的密码的用例,则无法使用 strong_password。您需要直接使用 service('passwords') 来检查密码。但请记住,为其他用户设置密码不是一个好习惯。这是因为密码应该只有该用户知道。