adt / doctrine-authenticator
适用于Nette框架的Doctrine身份验证器。
v1.6
2024-03-24 09:45 UTC
Requires
- php: >=8.1
- doctrine/orm: ^2.9
- nette/http: ^3.0
- nette/security: ^3.2
README
- 允许您使用Doctrine实体作为Nette身份
- 使用cookie而不是PHP会话
- 保存IP地址和User-Agent头信息以更好地检测滥用
- 检测无效令牌并调用onInvalidToken回调以记录和防止可能的滥用
- 当启用fraudDetection时,在具有不同User-Agent头信息和IP地址的情况下使令牌无效,并调用onFraudDetection回调以记录和防止可能的滥用
安装
composer require adt/doctrine-authenticator
配置
1) Neon配置
services: security.user: App\Model\Security\SecurityUser security.userStorage: Nette\Bridges\SecurityHttp\CookieStorage security.authenticator: factory: App\Model\Security\Authenticator(expiration: '14 days') setup: - setFraudDetection(true) # you can disable it for automatic tests for example
通过属性添加新的映射,例如(如果您使用nettrine)
nettrine.orm.attributes: mapping: ADT\DoctrineAuthenticator: %appDir%/../vendor/adt/doctrine-authenticator/src
或通过注解
nettrine.orm.annotations: mapping: ADT\DoctrineAuthenticator: %appDir%/../vendor/adt/doctrine-authenticator/src
2) 创建实现ADT\DoctrineAuthenticator\DoctrineAuthenticatorIdentity的Identity实体
并根据您的需求进行调整。
<?php namespace App\Model\Entities; use ADT\DoctrineAuthenticator\DoctrineAuthenticatorIdentity; use Doctrine\ORM\Mapping\Column; use Doctrine\ORM\Mapping\Entity; use Doctrine\ORM\Mapping\GeneratedValue; use Doctrine\ORM\Mapping\Id; /** @Entity */ #[Entity] class Identity implements DoctrineAuthenticatorIdentity { /** * @Id * @Column * @GeneratedValue */ #[Id] #[Column] #[GeneratedValue] protected ?int $id; public function getId(): int { return $this->id; } public function __clone() { $this->id = null; } /** @Column(unique=true) */ #[Column(unique: true)] protected string $email; /** @Column */ #[Column] protected string $password; public function getEmail(): string { return $this->email; } public function setEmail(string $email): self { $this->email = $email; return $this; } public function getPassword(): string { return $this->password; } public function setPassword(string $password): self { $this->password = $password; return $this; } public function getRoles(): array { return []; } public function getAuthObjectId(): string { return (string) $this->getId(); } }
3) 创建扩展ADT\DoctrineAuthenticator\SecurityUser的SecurityUser服务
<?php namespace App\Model\Security; use App\Model\Entities\Identity; /** * @method Identity getIdentity() */ class SecurityUser extends \ADT\DoctrineAuthenticator\SecurityUser { }
4) 创建扩展ADT\DoctrineAuthenticator\DoctrineAuthenticator的Authenticator
并调整方法authenticate
和getIdentity
以满足您的需求。
<?php namespace App\Model\Security; use ADT\DoctrineAuthenticator\DoctrineAuthenticator; use App\Model\Entities\Identity; use Doctrine\DBAL\Connection; use Doctrine\ORM\Configuration; use Doctrine\ORM\EntityManagerInterface; use Nette\Bridges\SecurityHttp\CookieStorage; use Nette\Http\Request; use Nette\Security\AuthenticationException; use Nette\Security\IIdentity; use Nette\Security\Passwords; class Authenticator extends DoctrineAuthenticator { public function __construct( string $expiration, CookieStorage $cookieStorage, Connection $connection, Configuration $configuration, Request $httpRequest, protected readonly EntityManagerInterface $em, ) { parent::__construct($expiration, $cookieStorage, $connection, $configuration, $httpRequest); $this->onInvalidToken = function(string $token) { // log probable fraud }; } public function authenticate(string $user, string $password): IIdentity { /** @var Identity $identity */ if (! $identity = $this->em->getRepository(Identity::class)->findOneBy(['email' => $user])) { throw new AuthenticationException('Identity not found!'); } if (!(new Passwords())->verify($password, $identity->getPassword())) { throw new AuthenticationException('Incorrect password!'); } return $identity; } public function getIdentity($id): IIdentity { return $this->em->getRepository(Identity::class)->find($id); } }
5) 生成迁移
例如,如下所示
php bin/console migrations:diff
用法
只需像往常一样在安全用户上调用login
$this->securityUser->login($email, $password);