沙尘暴/usermanagement

用于用户管理、登录/登出、密码重置和用户激活的Neos和Flow包

安装次数: 24,908

依赖: 0

建议者: 0

安全: 0

星标: 37

关注者: 12

分支: 28

公开问题: 20

类型:neos-package

7.1.4 2022-06-29 11:42 UTC

README

0. 功能

此包在Neos CMS和Flow中运行,并提供了以下功能

  • 通过注册表单注册(前端)用户
  • 发送账户确认电子邮件
  • 通过登录表单登录已注册的(前端)用户
  • "忘记密码"以及密码重置电子邮件

1. 兼容性和维护

Sandstorm.UserManagement目前维护以下版本

版本5.x中的重大更改

配置更改

由于我已经移除了对swiftmailer的直接依赖,转而使用Sandstorm/TemplateMailer包(它提供了css内联),因此在此包中删除了EmailService。这意味着您需要更改一些配置选项,因为它们现在设置在Sandstorm.TemplateMailer配置路径中,而不是在Sandstom.UserManagement路径中。请参阅Sandstorm/TemplateMailer文档,了解如何设置以下配置

  • senderAddress
  • senderName
  • templatePackage

提示:要覆盖此包的发送地址,您需要以下设置

Sandstorm:
  TemplateMailer:
    senderAddresses:
      sandstorm_usermanagement_sender_email: # You need to use this exact key to override the UserManagement defaults
        name: Your-App
        address: yoursenderemail@yourapp.de

电子邮件模板更改

在注册电子邮件模板中,默认情况下不再提供两个变量

  • "applicationName"(填充已配置的电子邮件senderAddress)
  • "email"(填充邮件发送到的电子邮件地址)然而,在注册电子邮件中,"registrationFlow"现在可用,这提供了对电子邮件以及用户在注册过程中输入的所有其他信息的访问(只要它们存储在RegistrationFlow对象中)。

要覆盖现有的激活和密码重置模板,请执行以下操作

2. 配置

设置

以下是基本配置步骤

  1. 在将此包添加后,运行./flow doctrine:migrate以安装其模型。该包自动通过在包设置中自动包含其路由来公开其路由。注意:在全局Routes.yaml中定义的任何路由都在此包的路由之前加载,因此它们可能会被覆盖。这对于默认的Flow子路由尤其如此,因此请确保您已从全局Routes.yaml中删除了它们。如果您无法删除它们,请在Flow子路由之前手动包含此包的子路由。

  2. 在您的包的composer.json中需要此包。这将通知Flow它需要在您的包之前加载UserManagement,这允许您覆盖配置并确保授权正确工作。请注意,您必须将此添加到所有使用用户管理功能的自定义包中 - 如果您的站点分为多个包或插件,这一点非常重要。以下是一个示例

{
    "description": "Your Site Package",
    "type": "neos-site", (or "neos-package" if you're using Flow only or building a Plugin)
    "require": {
        "neos/neos": "*",
        "sandstorm/usermanagement": "*"
    }
    ...more settings here...
}
  1. 运行 ./flow neos.flow:package:rescan 以重新生成加载所有包的顺序。

  2. 将以下配置设置添加并适应到您的配置文件中(请确保不要错过特殊的 Neos 设置)。

基本配置选项

这些是电子邮件、超时等基本配置选项。通常,您会希望根据应用程序对其进行调整。

Sandstorm:
  UserManagement:
    # Validity timespan for the activation token for newly registered users.
    activationTokenTimeout: '2 days'
    # Validity timespan for the token used to reset passwords.
    resetPasswordTokenTimeout: '4 hours'
    # The message that appears if a user could not be logged in.
    authFailedMessage:
      title: 'Login nicht möglich'
      body: 'Sie haben ungültige Zugangsdaten eingegeben. Bitte versuchen Sie es noch einmal.'
    # Email settings
    email:
      # Subject line for the account confirmation email
      subjectActivation: 'Please confirm your account'
      # Subject line for the password reset email
      subjectResetPassword: 'Password reset'
    # An array of roles which are assigned to users after they activate their account.
    rolesForNewUsers: []

I18N

可以使用 i18n 对设置中配置的消息。只需将值设置为 'i18n' 即可。

Sandstorm:
  UserManagement:
    authFailedMessage:
      title: 'i18n'
      body: 'i18n'
    email:
      subjectActivation: 'i18n'
      subjectResetPassword: 'i18n'

Neos 中使用的附加设置

您应该将重定向和用户创建服务的实现切换到 Neos 服务。将其添加到您的 Objects.yaml 文件中。

# Use the Neos services
Sandstorm\UserManagement\Domain\Service\RedirectTargetServiceInterface:
  className: 'Sandstorm\UserManagement\Domain\Service\Neos\NeosRedirectTargetService'
Sandstorm\UserManagement\Domain\Service\UserCreationServiceInterface:
  className: 'Sandstorm\UserManagement\Domain\Service\Neos\NeosUserCreationService'

请注意,由于此包模板中的原因,NeosUserCreationService 需要 RegistrationFlow 属性中存在非空的 firstName 和 lastName。

Neos 3.0 及更高版本

将以下内容添加到您的包(或全局)的 Settings.yaml 文件中。这创建了一个单独的认证提供程序,以便 Neos 可以区分前端和后端登录。

Neos:
  Flow:
    security:
      authentication:
        providers:
          'Neos.Neos:Backend':
            requestPatterns:
              Sandstorm.UserManagement:NeosBackend:
                pattern: Sandstorm\UserManagement\Security\NeosRequestPattern
                patternOptions:
                  'area': 'backend'
          'Sandstorm.UserManagement:Login':
            provider: PersistedUsernamePasswordProvider
            requestPatterns:
              Sandstorm.UserManagement:NeosFrontend:
                pattern: Sandstorm\UserManagement\Security\NeosRequestPattern
                patternOptions:
                  'area': 'frontend'

Neos 2.3 (Flow 3.3)

在 Neos 3.0 之前,Neos.Neos:Backend 认证提供程序称为 Typo3BackendProvider。在上面的配置中,将 Neos.Neos:Backend 替换为 Typo3BackendProvider

3. 使用

CLI 命令

创建用户

该包公开了一个创建用户的命令。您可以运行

./flow sandstormuser:create test@example.com password --additionalAttributes="firstName:Max;lastName:Mustermann"

来创建用户。如果您在 Neos 中使用该包,这将创建一个 Neos 用户。您可以在 Neos 后端之后分配角色给新用户。

确认用户注册

可以通过运行以下命令确认注册流程并触发用户创建:

./flow sandstormuser:activateregistration test@example.com

重置密码

从 1.1.2 版本开始,可以使用此包创建的用户重置密码。

./flow sandstormuser:setpassword test@example.com password

如果包检测到正在使用 NeosUserCreationService,则将命令转发到 Neos 的 UserCommandController->setPasswordCommand()。否则,将使用我们包的自身逻辑。

可以将认证提供程序作为可选参数传递,以重置使用默认用户管理以外的其他提供程序创建的用户密码(Sandstorm.UserManagement:Login

./flow sandstormuser:setpassword test@example.com password --authenticationProvider=Typo3BackendProvider

登录/注销后的重定向

通过配置

要定义用户登录或注销后应重定向到何处,您可以设置一些配置选项

Sandstorm:
  UserManagement:
    redirect:
    # To activate redirection, make these settings:
      afterLogin:
        action: 'action'
        controller: 'Controller'
        package: 'Your.Package'
      afterLogout:
        action: 'action'
        controller: 'Controller'
        package: 'Your.Package'

通过节点属性

当在 Neos 中使用此包时,您还有另一个选择:您可以在 LoginForm 节点类型上设置属性。您链接到此处的工作表将在用户登录或注销后显示。请注意,如果登录/注销表单显示在受限页面上:在这种情况下,您必须设置重定向目标,否则您将在注销时收到错误消息。如果重定向是通过 Settings.yaml 配置的,它们将优先于节点的配置。当然,如果您在模板中直接有登录/注销表单,您也可以从 TypoScript 设置这些属性。

loginform = Sandstorm.UserManagement:LoginForm {
  // This should be set, or there will be problems when you have multiple plugins on a page
  argumentNamespace = 'login'
  // Redirect to the parent page automatically after logout
  redirectAfterLogout = ${q(documentNode).parent().get(0)}
}

通过自定义 RedirectTargetService

如果将用户重定向到特定控制器方法仍然不足以满足您的需求,您可以直接实现 RedirectTargetServiceInterface。只需在您的包内添加实现,并在 Objects.yaml 中添加以下行。请注意包加载顺序,您的包应在 composer.json 中要求 sandstorm/usermanagement。

Sandstorm\UserManagement\Domain\Service\RedirectTargetServiceInterface:
  className: 'Your\Package\Domain\Service\YourCustomRedirectTargetService'

在模板中检查已登录用户

有一个 ViewHelper 允许您检查是否有人在前端登录。以下是一个示例

{namespace um=Sandstorm\UserManagement\ViewHelpers}

<um:ifAuthenticated>
  <f:then>
    You are currently logged in.
  </f:then>
  <f:else>
    You are not logged in!
  </f:else>
</um:ifAuthenticated>

如果您已配置了与默认认证提供程序不同的认证提供程序,则 viewhelper 有一个 authenticationProviderName 参数,您可以传递您使用的认证提供程序名称。

扩展包

更改/覆盖模板

您可以通过默认方法使用 Views.yaml 修改任何模板。请参阅 http://flowframework.readthedocs.io/en/stable/TheDefinitiveGuide/PartIII/ModelViewController.html#configuring-views-through-views-yaml。以下是一个如何插入您自己的登录模板的示例

-
  requestFilter: 'mainRequest.isPackage("Neos.Neos") && isPackage("Sandstorm.UserManagement") && isController("Login") && isAction("login")'
  options:
    templatePathAndFilename: 'resource://Your.Package/Private/Templates/Login/Login.html'
    partialRootPaths: ['resource://Your.Package/Private/Partials']
    layoutRootPaths: ['resource://Your.Package/Private/Layouts']

覆盖电子邮件模板

如上配置选项中所述,覆盖电子邮件模板很简单

  • 将 UserManagement 的 Resources/Private 文件夹中的 EmailTemplates 文件夹复制到您的自己的包中,并根据您的意愿修改模板。
  • 按照 Sandstorm/TemplateMailer 文档 中的说明,将您的自己的包添加到模板Packages配置中。

修改用户模型

您可能想向用户模型中添加更多信息。这可以通过扩展与此包一起提供的用户模型并添加您喜欢的属性来完成。然后您需要替换 UserCreationServiceInterface 的实现来控制创建过程。这可以通过 Objects.yaml 来完成。

Sandstorm\UserManagement\Domain\Service\UserCreationServiceInterface:
  className: 'Your\Package\Domain\Service\YourCustomUserCreationService'

挂钩到登录/登出过程

UserManagement 包在登录和登出过程中会发出三个信号,您可以通过 Flows 的 信号和槽 机制挂钩。例如,您可以在用户登录时设置额外的cookie,例如启用与其他服务的JWT身份验证。以下是一个使用所有三个信号的示例,您可以将此复制到您自己的 Package.php 文件中

public function boot(Bootstrap $bootstrap) {
    $dispatcher = $bootstrap->getSignalSlotDispatcher();
    $dispatcher->connect(
        \Sandstorm\UserManagement\Controller\LoginController::class, 'authenticationSuccess',
        \Your\Package\Domain\Service\ExampleService::class, 'onAuthenticationSuccess'
    );
    $dispatcher->connect(
        \Sandstorm\UserManagement\Controller\LoginController::class, 'authenticationFailure',
        \Your\Package\Domain\Service\ExampleService::class, 'onAuthenticationFailure'
    );
    $dispatcher->connect(
        \Sandstorm\UserManagement\Controller\LoginController::class, 'logout',
        \Your\Package\Domain\Service\ExampleService::class, 'onLogout'
    );
}

然后,您的示例服务可能看起来像这样

namespace Your\Package\Domain\Service;

use Neos\Flow\Mvc\ActionRequest;
use Neos\Flow\Mvc\Controller\ControllerContext;
use Neos\Flow\Security\Exception\AuthenticationRequiredException;

class ExampleService
{
    public function onAuthenticationSuccess(ControllerContext $controllerContext, ActionRequest $originalRequest = null)
    {
        // Do custom stuff here
    }

    public function onAuthenticationFailure(ControllerContext $controllerContext, AuthenticationRequiredException $exception = null)
    {
        // Do custom stuff here
    }

    public function onLogout(ControllerContext $controllerContext)
    {
        // Do custom stuff here
    }
}

修改注册流程和验证逻辑

RegistrationFlow 类代表用户注册您的应用程序。它有一些默认属性,可以通过其 attributes 属性扩展为任意额外的数据。

向注册流程添加自定义字段

按照上述说明替换注册模板并添加一个字段

<f:form.checkbox id="terms" property="attributes.terms" value=""/>

这将添加该字段,但当然您可能还想对其进行验证。

扩展注册流程验证逻辑

UserManagement 包提供了一个钩子,您可以通过它实现自己的自定义注册流程验证逻辑。它直接从包的领域模型验证器调用。您需要做的就是创建一个实现 Sandstorm\UserManagement\Domain\Service\RegistrationFlowValidationServiceInterface 的实现。它可能看起来像这样

class RegistrationFlowValidationService implements RegistrationFlowValidationServiceInterface {
    /**
     * @param RegistrationFlow $registrationFlow
     * @param RegistrationFlowValidator $validator
     * @return void
     */
    public function validateRegistrationFlow(RegistrationFlow $registrationFlow, RegistrationFlowValidator $validator) {
        // This is an example of your own custom validation logic.
        if ($registrationFlow->getAttributes()['agb'] !== '1') {
            $validator->getResult()->forProperty('attributes.terms')->addError(new \Neos\Flow\Validation\Error('You need to accept the terms and conditions.'));
        }
    }
}

4. 运行测试

使用以下命令运行所有测试:./bin/phpunit -c ./Build/BuildEssentials/PhpUnit/UnitTests.xml Packages/Application/Sandstorm.UserManagement/Tests/Unit

5. 已知问题

请随时提交问题/PR

6. TODOs

  • 更多测试。

7. 常见问题解答

  • 如果用户没有收到注册邮件会发生什么? 只需告诉用户重新注册即可。在这种情况下,之前的未完成注册将被丢弃。

8. 许可证

MIT. https://open-source.org.cn/licenses/MIT