teresko/palladium

用户认证和注册组件

v1.4.2 2017-11-14 11:25 UTC

This package is auto-updated.

Last update: 2024-09-27 19:12:25 UTC


README

(工作进度:2.0版本文档)

Build Status Packagist Version License Code Climate Code Coverage Scrutinizer Code Quality Infection MSI

用于处理用户身份识别的库。

该库的目的是定位给定身份证明的用户账户(确切地说,是其唯一ID),并管理各种类型的身份。它由4个不同的服务组成:识别、注册、搜索和恢复。

安装

您可以使用以下命令使用composer将库添加到您的项目中

composer require teresko/palladium

使用此包需要PHP版本7.0+和PDO。

您还需要创建一个表,用于存储标识信息。示例模式可在此处找到。它目前仅包含MySQL/MariaDB的表定义,但该库可以与任何具有PDO驱动的RDBMS一起使用。

初始化

Palladium包含4个服务:RegistrationIdentificationSearchRecovery。这些服务中的每一个都有两个强制依赖项

  • 仓库(实现Palladium\Contract\CanPersistIdenity
  • 日志记录器(实现Psr\Log\LoggerInterface

这为您提供了替换默认仓库的选项,如果您想更改或替换持久化抽象层的一部分。至于日志记录器,建议使用Monolog,但与任何兼容的日志系统都应能正常工作。

默认仓库还包含添加自定义身份类型和数据映射器的功能,这些映射器用于您或内置的身份类型。有关使用详情,请参阅%TODO%部分。

可选参数

Identification服务的构造函数中,有一个可选的第三和第四参数

  • cookie的生命周期(以秒为单位),默认为4小时。
  • hash成本(用于BCrypt),默认为12

Registration服务的构造函数中,有一个可选的第三参数

  • hash成本(用于BCrypt),默认为12

设置仓库

如上所述,所有4个服务都期望一个仓库作为构造函数依赖项。如果您不替换捆绑的仓库以使用自定义版本,那么您需要初始化Palladium\Repository\Identity并将其传递给服务。

捆绑的仓库本身只有一个依赖项:实现Palladium\Contract\CanCreateMapper的实例。该契约(接口)由Palladium\Component\MapperFactory实现。此工厂有两个依赖项:PDO实例和存储标识信息的表名。

<?php

$factory = new \Palladium\Component\MapperFactory(new \PDO(...$config), $tableName);
$repository = new \Palladium\Repository\Identity($factory);

在所有其他代码示例中,如果您看到使用$repository变量的地方,您可以假设它已经使用此代码示例进行了初始化。

与DI容器一起使用

对于使用Symfony的DependencyInjection Component(版本:3.4+)的用户,有一个示例配置文件:%TODO%

用法

注册新的身份

<?php

$registration = new \Palladium\Service\Registration($repository, $logger);

$identity = $registration->createStandardIdentity('foo@bar.com', 'password');
$registration->bindAccountToIdentity($accountId, $identity);

如果操作成功完成,变量$identity将包含一个未经验证的StandardIdentity实例。[StandardIdentity](https://github.com/teresko/palladium/blob/master/src/Palladium/Entity/StandardIdentity.php)。要完成验证,您必须使用身份中包含的令牌。在给出的示例中,此令牌可以通过$instance->getToken()来获取。

如果电子邮件已被用于另一个身份,则createStandardIdentity()方法可能会抛出IdentityConflict异常。

createStandardIdentity()方法有一个可选的第三个参数,它定义了电子邮件验证令牌的持续时间(以秒为单位)。应用后,前面的示例如下所示:

<?php

$registration = new \Palladium\Service\Registration($repository, $logger);

$identity = $registration->createStandardIdentity('foo@bar.com', 'password', 3600);
$registration->bindAccountToIdentity($accountId, $identity);

这将使验证令牌在用户身份注册后的1小时内可用。在此给定时间过后,您将无法使用findStandardIdentityByToken()Search服务中找到此身份。

重要createStandardIdentity()方法不验证用户的电子邮件或其他类型的标识符。它只检查其唯一性。电子邮件、电话号码、昵称和其他标识符的验证超出了此库的范围。

身份验证

<?php

$search = new \Palladium\Service\Search($repository, $logger);
$registration = new \Palladium\Service\Registration($repository, $logger);

$identity = $search->findStandardIdentityByToken($token, \Palladium\Entity\Identity::ACTION_VERIFY);
$registration->verifyStandardIdentity($identity);

使用$token值定位匹配的EmailIdentity,然后进行验证。如果找不到身份,则findStandardIdentityByToken()将抛出IdentityNotFound异常。

使用电子邮件和密码登录

<?php

$search = new \Palladium\Service\Search($repository, $logger);
$identification = new \Palladium\Service\Identification($repository, $logger);

$identity = $search->findStandardIdentityByIdentifier($identifier);
$cookie = $identification->loginWithPassword($identity, $password);

如果没有找到与给定标识符(例如,电子邮件地址)匹配的身份,则findStandardIdentityByIdentifier()方法将抛出IdentityNotFound异常。

如果密码不匹配,则loginWithPassword()方法将抛出PasswordMismatch异常。

创建新的单次使用登录

<?php

$identity = $this->registration->createNonceIdentity($accountId);

这将创建一个新的NonceIdentity实例。要使用它进行登录,您需要使用NonceIdentity::getIdentifier()NonceIdentity::getKey()中的值,其中标识符将用于定位一次性身份,而密钥将用于验证。

当应用时,createNonceIdentity()方法有一个可选的第二个参数,它定义了此一次性身份的持续时间(以秒为单位)。应用后的示例如下所示:

<?php

$identity = $this->registration->createNonceIdentity($accountId, 600);

这将使一次性身份在其创建后的10分钟内可用。在此允许的时间过后,将此身份传递到IdentificationuseNonceIdentity()方法中将导致抛出IdentityExpired异常。

使用一次性令牌登录

<?php

$identity = $this->search->findNonceIdentityByIdentifier($identifier);
$cookie = $this->identification->useNonceIdentity($identity, $key);

如果没有找到与给定标识符(电子邮件地址、昵称等)匹配的身份,则findNonceIdentityByIdentifier()方法将抛出IdentityNotFound异常。

如果密码不匹配,则useNonceIdentity()方法将抛出KeyMismatch异常。

使用cookie登录

<?php

$search = new \Palladium\Service\Search($repository, $logger);
$identification = new \Palladium\Service\Identification($repository, $logger);

$identity = $search->findCookieIdentity($accountId, $series);
$cookie = $identification->loginWithCookie($identity, $key);

如果使用findCookieIdentity()找不到cookie,将会抛出一个标准的IdentityNotFound异常。导致这种情况的可能原因包括cookie已不再活跃(例如,用户注销)或cookie根本不存在。

如果cookie太旧,loginWithCookie()将产生IdentityExpired异常。

但是,loginWithCookie()方法也可能产生CompromisedCookie异常。出现此类异常可能表明cookie已被盗用,或者用户从未收到新的cookie值。

阻止受损的cookie

<?php

$search = new \Palladium\Service\Search($repository, $logger);
$identification = new \Palladium\Service\Identification($repository, $logger);

$identity = $search->findCookieIdentity($accountId, $series);
$identification->blockIdentity($identity);

这是处理可疑cookie(可能已遭盗用)的推荐方法。这并非用于注销用户

注销

<?php

$search = new \Palladium\Service\Search($repository, $logger);
$identification = new \Palladium\Service\Identification($repository, $logger);

$identity = $search->findCookieIdentity($accountId, $series);
$identification->logout($identity, $key);

此操作将cookie标记为“已丢弃”。可以产生的异常列表与使用cookie登录部分中描述的相同。

启动密码重置过程

<?php

$search = new \Palladium\Service\Search($repository, $logger);
$recovery = new \Palladium\Service\Recovery($repository, $logger);

$identity = $search->findStandardIdentityByIdentifier($identifier);
$token = $recovery->markForReset($identity);

如果找不到与给定电子邮件地址匹配的标识符,findStandardIdentityByIdentifier()方法将抛出IdentityNotFound异常。

当调用markForReset()时,必须提供已验证的StandardIdentity实例(否则,可能会导致您的应用程序泄露用户的私人信息)。如果不是这种情况,该方法将抛出IdentityNotVerified异常。

markForReset()方法有一个可选的第二个参数,它定义了密码重置令牌的有效期(以秒为单位)。应用后,前面的示例如下所示

<?php

$search = new \Palladium\Service\Search($repository, $logger);
$recovery = new \Palladium\Service\Recovery($repository, $logger);

$identity = $search->findStandardIdentityByIdentifier($identifier);
$token = $recovery->markForReset($identity, 7200);

这将使密码重置令牌在用户标识被标记为重置后的两小时内可用。当允许的时间过期后,您将无法在Search服务中使用findEmailIdentityByToken()找到此标识。

密码重置完成

<?php

$search = new \Palladium\Service\Search($repository, $logger);
$recovery = new \Palladium\Service\Recovery($repository, $logger);

$identity = $search->findEmailIdentityByToken($token, \Palladium\Entity\Identity::ACTION_RESET);
$recovery->resetIdentityPassword($identity, 'foobar');

如果找不到与给定令牌匹配的标识符,findEmailIdentityByToken()方法将抛出IdentityNotFound异常。

更改电子邮件身份的密码

<?php

$search = new \Palladium\Service\Search($repository, $logger);
$identification = new \Palladium\Service\Identification($repository, $logger);

$identity = $search->findStandardIdentityByIdentifier($identifier);
$identification->changePassword($identity, $oldPassword, $newPassword);

如果找不到与给定电子邮件地址(或任何其他类型的标识符)匹配的标识符,findStandardIdentityByIdentifier()方法将抛出IdentityNotFound异常。

如果密码不匹配,changePassword()方法将抛出PasswordMismatch异常。

批量注销身份

<?php

$search = new \Palladium\Service\Search($repository, $logger);
$identification = new \Palladium\Service\Identification($factory, $logger);

$list = $search->findIdentitiesByParentId($identity->getId());
$identification->discardIdentityCollection($list);

findIdentitiesByParentId()的返回值将返回一个可能为空的IdentityCollection

记录用户活动

如前所述,此库中的服务期望一个PSR-3兼容的日志记录器作为依赖项。它将用于记录三个级别的事件

LogLevel::INFO

此日志级别用于跟踪用户在使用应用程序时按预期执行的操作

  • 成功注册
  • 成功恢复密码
  • 成功登录(使用电子邮件/用户名或cookie)或注销
  • 成功验证电子邮件
  • 使用过期的cookie或nonce

LogLevel::NOTICE

当用户尝试了不应在正确使用场景中发生的失败操作时,将记录此级别的日志。

  • 所有身份未找到的情况
  • 输入了错误的密码
  • 标识符已被用于不同的身份
  • 尝试使用未经验证的邮箱恢复密码

LogLevel::WARNING

仅用于记录用户尝试使用受损cookie的情况。

附加说明

此库专注于一项特定任务。它包含以下任何功能:

  • 账户创建和管理
  • 授权系统
  • 用户输入验证(包括电子邮件和密码)
  • 日志框架

如果您认为身份验证库需要上述列出的任何部分,那么这并非您要寻找的库。