PHP项目Symfony PasswordHasher

wen PHP项目 1

本文目录导读:

PHP项目Symfony PasswordHasher

  1. 基本概念
  2. 安装
  3. 基本用法
  4. 配置方式
  5. 在实体类中使用
  6. 高级用法
  7. 密码迁移策略
  8. 安全建议
  9. 测试辅助

我来帮你详细介绍Symfony的PasswordHasher组件,这是Symfony 5.3+版本中处理密码加密与验证的官方工具。

基本概念

PasswordHasher 替代了旧版的Encoder组件,提供了更现代、更安全的密码处理方式。

安装

composer require symfony/password-hasher

基本用法

加密密码

use Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactory;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasher;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
// 创建哈希工厂
$factory = new PasswordHasherFactory([
    'common' => ['algorithm' => 'auto'],
    'legacy' => ['algorithm' => 'bcrypt', 'cost' => 10],
]);
// 创建密码哈希器
$passwordHasher = new UserPasswordHasher($factory);
// 加密密码
$hashedPassword = $passwordHasher->hashPassword(
    $user, // 必须是PasswordAuthenticatedUserInterface实例
    'plainPassword123'
);

验证密码

// 验证密码
$isValid = $passwordHasher->isPasswordValid(
    $user,
    'plainPassword123'
); // 返回 true/false
// 检查是否需要重新加密
$needsRehash = $passwordHasher->needsRehash($user);

配置方式

YAML配置(security.yaml)

security:
    password_hashers:
        Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
            algorithm: auto
            cost: 12
            # time_cost: 3 # Argon2i额外参数
            # memory_cost: 10 # Argon2i额外参数
            # threads: 2 # Argon2i额外参数

支持的算法

security:
    password_hashers:
        App\Entity\User:
            algorithm: bcrypt
            cost: 12
        App\Entity\LegacyUser:
            algorithm: sodium
            # 或
            # algorithm: auto (推荐)

在实体类中使用

实现接口

namespace App\Entity;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
class User implements UserInterface, PasswordAuthenticatedUserInterface
{
    private string $password;
    public function getPassword(): ?string
    {
        return $this->password;
    }
    public function setPassword(string $password): self
    {
        $this->password = $password;
        return $this;
    }
    // 其他接口方法...
    public function getSalt(): ?string { return null; }
    public function eraseCredentials(): void { }
    public function getUserIdentifier(): string { return $this->email; }
    public function getRoles(): array { return ['ROLE_USER']; }
}

注册时加密密码

// UserController.php
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
class RegistrationController extends AbstractController
{
    #[Route('/register', name: 'app_register')]
    public function register(
        Request $request,
        UserPasswordHasherInterface $passwordHasher,
        EntityManagerInterface $entityManager
    ): Response {
        $user = new User();
        $form = $this->createForm(RegistrationFormType::class, $user);
        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            // 加密密码
            $user->setPassword(
                $passwordHasher->hashPassword(
                    $user,
                    $form->get('plainPassword')->getData()
                )
            );
            $entityManager->persist($user);
            $entityManager->flush();
            return $this->redirectToRoute('app_login');
        }
        return $this->render('registration/register.html.twig', [
            'registrationForm' => $form->createView(),
        ]);
    }
}

高级用法

自定义哈希器

use Symfony\Component\PasswordHasher\Hasher\CheckPasswordLengthTrait;
use Symfony\Component\PasswordHasher\PasswordHasherInterface;
class CustomPasswordHasher implements PasswordHasherInterface
{
    use CheckPasswordLengthTrait;
    public function hash(string $plainPassword): string
    {
        // 自定义加密逻辑
        return hash('sha256', $plainPassword . 'your_salt');
    }
    public function verify(string $hashedPassword, string $plainPassword): bool
    {
        return $hashedPassword === $this->hash($plainPassword);
    }
    public function needsRehash(string $hashedPassword): bool
    {
        return false;
    }
}

多用户类型配置

security:
    password_hashers:
        App\Entity\Admin:
            algorithm: sodium
            memory_cost: 256000
            time_cost: 3
        App\Entity\Client:
            algorithm: bcrypt
            cost: 10
        App\Entity\ApiUser:
            algorithm: auto
            migrate_from:
                - bcrypt
                - legacy_hash

密码迁移策略

当需要从旧算法迁移到新算法时:

#[AsPasswordUpgrade]
public function onPasswordUpgrade(
    PasswordUpgraderInterface $passwordUpgrader,
    UserInterface $user,
    string $plainPassword
): void {
    // 自动升级密码哈希算法
    $passwordUpgrader->upgradePassword($user, $plainPassword);
}

安全建议

  1. 始终使用auto算法:它会自动选择当前最安全的算法
  2. 密码长度限制:默认密码最长4096字符
  3. 不使用过时算法:避免使用MD5、SHA1等
  4. 定期更新算法:随着时间推移升级加密强度

测试辅助

use Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactory;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasher;
// 测试中创建简单哈希器
$passwordHasher = new UserPasswordHasher(
    new PasswordHasherFactory([
        User::class => ['algorithm' => 'bcrypt', 'cost' => 4] // 低cost加速测试
    ])
);

使用Symfony PasswordHasher可以轻松实现安全的密码管理,它自动处理了算法选择、哈希盐、加密强度等复杂细节。

抱歉,评论功能暂时关闭!