You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不使用Doctrine的情况下实现Symfony 5身份认证?

不依赖Doctrine实现Symfony 5.3 Authenticator-based 身份认证方案

以下是完整的落地步骤,全程不需要引入任何Doctrine相关组件:

1. 实现自定义User类

首先创建符合Symfony安全规范的User实体,不需要加任何Doctrine注解,直接实现UserInterface和PasswordAuthenticatedUserInterface两个接口即可:

<?php
namespace App\Entity;

use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;

class User implements UserInterface, PasswordAuthenticatedUserInterface
{
    private $id;
    private $email;
    private $password;
    private $name;
    private $roles = [];

    // 自行添加各字段的getter、setter方法
    public function getId(): ?int
    {
        return $this->id;
    }

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

    public function getPassword(): ?string
    {
        return $this->password;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function getRoles(): array
    {
        $roles = $this->roles;
        $roles[] = 'ROLE_USER';
        return array_unique($roles);
    }

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

    public function eraseCredentials()
    {
        // 不需要处理敏感数据的话留空即可
    }
}

2. 实现自定义UserProvider

创建自定义用户提供器,实现UserLoaderInterface接口,所有用户查询逻辑直接使用你项目现有数据库操作方式(PDO、自定义数据库层均可,以下用PDO做示例):

<?php
namespace App\Security;

use App\Entity\User;
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserLoaderInterface;

class CustomUserProvider implements UserLoaderInterface
{
    private $pdo;

    // 注入你项目的数据库连接实例即可,不需要用Doctrine
    public function __construct(\PDO $pdo)
    {
        $this->pdo = $pdo;
    }

    public function loadUserByIdentifier(string $identifier): UserInterface
    {
        $stmt = $this->pdo->prepare('SELECT id, email, password, name, roles FROM user WHERE email = ?');
        $stmt->execute([$identifier]);
        $userData = $stmt->fetch(\PDO::FETCH_ASSOC);

        if (!$userData) {
            throw new UserNotFoundException();
        }

        $user = new User();
        $user->setId($userData['id']);
        $user->setEmail($userData['email']);
        $user->setPassword($userData['password']);
        $user->setName($userData['name']);
        $user->setRoles(json_decode($userData['roles'], true) ?? []);

        return $user;
    }
}

3. 配置安全组件

修改config/packages/security.yaml配置,指定使用你自定义的用户提供器:

security:
    password_hashers:
        App\Entity\User:
            algorithm: auto
    providers:
        app_user_provider:
            id: App\Security\CustomUserProvider
    firewalls:
        main:
            lazy: true
            provider: app_user_provider
            # 如果你用表单登录,直接开启内置的form_login即可
            form_login:
                login_path: app_login
                check_path: app_login
                username_parameter: email
                password_parameter: password
            logout:
                path: app_logout
    access_control:
        # 按你项目需求配置权限规则即可
        - { path: ^/login, roles: PUBLIC_ACCESS }
        - { path: ^/, roles: ROLE_USER }

4. 实现登录控制器

登录控制器逻辑和官方示例完全一致,不需要做特殊修改:

<?php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;

class LoginController extends AbstractController
{
    #[Route('/login', name: 'app_login')]
    public function index(AuthenticationUtils $authenticationUtils): Response
    {
        $error = $authenticationUtils->getLastAuthenticationError();
        $lastUsername = $authenticationUtils->getLastUsername();

        return $this->render('login/index.html.twig', [
            'last_username' => $lastUsername,
            'error' => $error,
        ]);
    }

    #[Route('/logout', name: 'app_logout')]
    public function logout()
    {
        // 不需要写任何逻辑,Symfony会自动处理
    }
}

注意事项

  • 如果你需要自定义登录逻辑(比如加验证码、登录成功后特殊跳转逻辑),可以自行实现AbstractLoginFormAuthenticator子类,配置到firewall的custom_authenticators节点下即可,不需要修改用户提供器的逻辑
  • 所有数据库操作都可以替换为你项目现有封装的数据库操作类,不需要强制使用PDO
  • 密码哈希校验、会话保持等逻辑Symfony安全组件会自动处理,不需要额外开发

内容的提问来源于stack exchange,提问作者Charles

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 10:15:02