【问题标题】:How to implement Symfony 5 Authentication without Doctrine?如何在没有 Doctrine 的情况下实现 Symfony 5 身份验证?
【发布时间】:2026-01-26 23:30:01
【问题描述】:

我正在将现有的 PHP 项目重写为 Symfony 5.3。我想将其身份验证系统升级到 Symfony 的。唯一的问题:在这个项目中,Doctrine 不是一个选项。

我怎样才能使用Symfony's authentication(可能与新的Authenticator-based Security一起使用)而不在任何地方调用Doctrine?

我知道我必须implement a UserLoaderInterface,但是the docs 使用Doctrine 的次数太多了,以至于我不知道该怎么做。

post I just mentioned 提出了类似的问题,但它仍然使用 Symfony 2,因此已经过时了。

我有一个数据库,其中包含必要的 User 表和常用列(ID、电子邮件、密码、姓名等)。

直截了当: 我如何在没有 Doctrine 的情况下使用Symfony's authentication(可能与新的Authenticator-based Security 一起使用)?

【问题讨论】:

  • 首先运行 bin/console make:user 并在询问您是否要使用 Doctrine 时回答 no。这将为您提供一个 Security\User 类以及一个空的 Security\UserProvider。 security.yaml 将被连接以使用您的提供程序。你只需要自己实现数据库的东西。 make:auth 应该像以前一样工作。
  • 哈。我刚刚注意到我是 2014 年回答您的 * 链接的人。有些问题是永恒的。
  • 我继续使用 make:user。一切顺利。我现在必须根据UserProvider.php中的方法添加必要的SQL来获取信息是否正确?我知道在 loadUserByIdentifier() 中放入什么((我想这里提到的东西:symfony.com/doc/current/security/…),但其他的(例如 refreshUser()、upgradePassword())将是一个挑战。
  • 使用 make:auth 时,它会询问我要验证哪个用户类。我在那里说什么?那是用户提供者吗?但我不是 100% 知道使用 make:auth 做什么。我已经有一个登录表单。那是为了创建登录/注销路由吗?另外:感谢您的提示。 2014 年不是我的问题,但很高兴看到你留下来。只是表明文档可以从 2014 年开始进行一些扩展。;-)
  • make:auth 最终要做的是创建一个 Authenticator 类,其中包含大部分需要进行身份验证的配置。选择登录表单验证器选项并为您的用户类输入 App\Security\User,假设您使用 make:user 的默认值。作为 make:auth 的替代方法,您可以根据文档在 security.yaml 中手动将 form_login 部分添加到防火墙。但我会说 make:auth 是推荐的方法。您可以调整生成的代码以使用您的登录表单。如果您愿意,可以尝试两种方式。

标签: symfony symfony5


【解决方案1】:

要在官方website 和本教程SymfonyCast 上进行配置,但基本上您可以根据需要对用户进行身份验证:

看下一个例子:

如果您的配置使用默认配置,请在 src\App\Security 文件夹中创建一个文件并创建 TokenAuthenticator 类,现在请参阅下面的代码,在这种情况下检查 App\Service\ExternalAuthenticator 类,谁将负责从其他服务或api获取信息并返回。

<?php

namespace App\Security;

use App\Example\Student;
use App\Service\ExternalAuthenticator;
use App\DTO\INFORMATIONFROMOTHERSERVICE;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
use Symfony\Component\Security\Core\Security;

final class TokenAuthenticator extends AbstractGuardAuthenticator
{
    /** @var Security */
    private $security;

    /** @var ExternalAuthenticator */
    private $externalAuthenticator;

    /** @var UrlGeneratorInterface */
    private $urlGenerator;

    public function __construct(
        Security $security,
        ExternalAuthenticator $externalAuthenticator
    ) {
        $this->security = $security;
        $this->externalAuthenticator = $externalAuthenticator;
    }

    /**
     * {@inheritDoc}
     */
    public function supports(Request $request)
    {
        //on this example, this guard must be using if on the request contains the word token
        $response = false;
        $apiKey = $request->query->get('token');
        if (!is_null($apiKey)) {
            $response = true;
        }

        return $response;
    }

    /**
     * {@inheritDoc}
     */
    public function getCredentials(Request $request)
    {
        $apiKey = $request->query->get('token');
        // Validate with anything you want, other service or api
        /** @var INFORMATIONFROMOTHERSERVICE**/
        $dtoToken = $this->externalAuthenticator->validateToken($apiKey, $simulator);

        return $dtoToken;
    }

    /**
     * @param INFORMATIONFROMOTHERSERVICE $credentials
     * @param UserProviderInterface $userProvider
     * @return INFORMATIONFROMOTHERSERVICE |UserInterface|null
     */
    public function getUser($credentials, UserProviderInterface $userProvider)
    {
        return $userProvider;
    }

    public function checkCredentials($credentials, UserInterface $user)
    {
        return true;
    }

    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
    {
        return new RedirectResponse($this->urlGenerator->generate('home_incorrect'));
    }

    public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey)
    {
        return new RedirectResponse($request->getPathInfo());
    }

    public function start(Request $request, AuthenticationException $authException = null)
    {
        return new RedirectResponse($this->urlGenerator->generate('home_incorrect'));
    }

    public function supportsRememberMe()
    {
        // todo
    }
}

现在外部服务必须返回 App\DTO\INFORMATIONFROMOTHERSERVICE 类,但是这个类必须实现 UserInterface,现在记住这一点。我们需要配置什么守卫必须负责什么路由,看下一个例子:

security:
    encoders:
        App\Entity\User:
            algorithm: bcrypt

    # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
    providers:
        # used to reload user from session & other features (e.g. switch_user)
        app_user_provider:
            entity:
                class: App\Entity\User
                property: email
        //You can use a 
        custom_provider:
            id : App\DTO\INFORMATIONFROMOTHERSERVICE
        # used to reload user from session & other features (e.g. switch_user)
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        survey:
            anonymous: true
            pattern: ^/(custom_path)/
            // The
            provider: custom_provider
            guard:
                // You can use as many authenticator that you want, but in the node entrypoint, you must choose who must be the default if only is one you could remove the entrypoint node, similar as the main firewall
                authenticators:
                    - App\Security\TokenAuthenticator
                    - App\Security\OtherAuthenticator
                entry_point: App\Security\OtherAuthenticator
        main:
            anonymous: true
            lazy: true
            provider: app_user_provider
            logout:
                path: app_logout
            guard:
                authenticators:
                    - App\Security\AppAuthenticator

另请参阅下一个documentation,它将指导您创建类 App\DTO\INFORMATIONFROMOTHERSERVICE。

希望这个回答对你有帮助

【讨论】:

  • 这不适用于 Symfony5.3 很多功能已被弃用,需要使用新的身份验证