跳到内容

Code-via-Email 身份验证

编辑此页

一个双因素身份验证提供程序,用于生成随机数字代码并通过电子邮件发送给用户。

身份验证如何工作

在成功验证后,它会生成一个随机数并将其持久化到用户实体中。该数字通过电子邮件发送给用户。然后用户必须输入该数字才能获得访问权限。

可以配置数字的位数

1
2
3
4
# config/packages/scheb_2fa.yaml
scheb_two_factor:
    email:
        digits: 6

安装

要使用此功能,您必须安装 scheb/2fa-email

1
composer require scheb/2fa-email

该程序包用于发送电子邮件的默认实现假设您正在使用 symfony/mailer。要安装该软件包

1
composer require symfony/mailer

您可以自由使用任何其他您喜欢的邮件发送库,但那样您必须实现一个自定义的邮件发送器类(说明如下)。

基本配置

要启用此身份验证方法,请将其添加到您的配置中

1
2
3
4
5
6
# config/packages/scheb_2fa.yaml
scheb_two_factor:
    email:
        enabled: true
        sender_email: no-reply@example.com
        sender_name: John Doe  # Optional

您的用户实体必须实现 Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface。身份验证代码必须被持久化,因此请确保它存储在一个持久化的字段中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?php

namespace Acme\Demo\Entity;

use Doctrine\ORM\Mapping as ORM;
use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface;
use Symfony\Component\Security\Core\User\UserInterface;

class User implements UserInterface, TwoFactorInterface
{
    /**
     * @ORM\Column(type="string")
     */
    private string $email;

    /**
     * @ORM\Column(type="string", nullable=true)
     */
    private ?string $authCode;

    // [...]

    public function isEmailAuthEnabled(): bool
    {
        return true; // This can be a persisted field to switch email code authentication on/off
    }

    public function getEmailAuthRecipient(): string
    {
        return $this->email;
    }

    public function getEmailAuthCode(): string
    {
        if (null === $this->authCode) {
            throw new \LogicException('The email authentication code was not set');
        }

        return $this->authCode;
    }

    public function setEmailAuthCode(string $authCode): void
    {
        $this->authCode = $authCode;
    }
}

配置参考

1
2
3
4
5
6
7
8
9
10
# config/packages/scheb_2fa.yaml
scheb_two_factor:
    email:
        enabled: true                  # If email authentication should be enabled, default false
        mailer: acme.custom_mailer_service  # Use alternative service to send the authentication code
        code_generator: acme.custom_code_generator_service  # Use alternative service to generate authentication code
        sender_email: me@example.com   # Sender email address
        sender_name: John Doe          # Sender name
        digits: 4                      # Number of digits in authentication code
        template: security/2fa_form.html.twig   # Template used to render the authentication form

自定义邮件发送器

默认情况下,电子邮件是纯文本且非常简单。如果您想要不同的样式(例如 HTML),您必须创建自己的邮件发送器服务。它必须实现 Scheb\TwoFactorBundle\Mailer\AuthCodeMailerInterface

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php

namespace Acme\Demo\Mailer;

use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface;
use Scheb\TwoFactorBundle\Mailer\AuthCodeMailerInterface;

class MyAuthCodeMailer implements AuthCodeMailerInterface
{
    // [...]

    public function sendAuthCode(TwoFactorInterface $user): void
    {
        $authCode = $user->getEmailAuthCode();

        // Send email
    }
}

然后将其注册为服务并更新您的配置

1
2
3
4
# config/packages/scheb_2fa.yaml
scheb_two_factor:
    email:
        mailer: acme.custom_mailer_service

重新发送身份验证码

当您使用程序包自带的默认身份验证代码生成器时,有一种简单的方法可以重新发送包含身份验证代码的电子邮件。获取/注入服务 scheb_two_factor.security.email.code_generator 并调用方法 reSend(\Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface $user)

自定义代码生成器

如果您想要以不同的方式生成代码,您可以拥有自己的代码生成器。创建一个实现 Scheb\TwoFactorBundle\Security\TwoFactor\Provider\Email\Generator\CodeGeneratorInterface 的服务,并在配置中注册它

1
2
3
4
# config/packages/scheb_2fa.yaml
scheb_two_factor:
    email:
        code_generator: acme.custom_code_generator_service

自定义身份验证表单模板

该程序包使用 Resources/views/Authentication/form.html.twig 来渲染身份验证表单。如果您想使用不同的模板,您可以简单地在配置中注册它

1
2
3
4
# config/packages/scheb_2fa.yaml
scheb_two_factor:
    email:
        template: security/2fa_form.html.twig

自定义表单渲染

在某些情况下,仅仅更改模板是不够的。例如,您在多个防火墙上使用双因素身份验证,并且您需要为每个防火墙以不同的方式渲染表单。在这种情况下,您可以实现一个表单渲染器来完全自定义渲染逻辑。

创建一个实现 Scheb\TwoFactorBundle\Security\TwoFactor\Provider\TwoFactorFormRendererInterface 的类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php

namespace Acme\Demo\FormRenderer;

use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\TwoFactorFormRendererInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class MyFormRenderer implements TwoFactorFormRendererInterface
{
    // [...]

    public function renderForm(Request $request, array $templateVars): Response
    {
        // Customize form rendering
    }
}

然后将其注册为服务并更新您的配置

1
2
3
4
# config/packages/scheb_2fa.yaml
scheb_two_factor:
    email:
        form_renderer: acme.custom_form_renderer_service
包括代码示例在内的这项工作,根据 Creative Commons BY-SA 3.0 许可协议获得许可。
目录
    版本