aura / auth
提供统一的接口,用于使用本地或远程身份验证系统对用户进行身份验证。
Requires
- php: >=7.2.0
Requires (Dev)
- acclimate/container: ^2
- phpunit/phpunit: ~8
- vimeo/psalm: ~v4.15
Suggests
- ext/imap: For IMAP/POP/NNTP integration.
- ext/ldap: For LDAP integration.
README
提供使用各种适配器实现的身份验证功能和会话跟踪;当前支持的适配器包括
- Apache htpasswd 文件
- 通过 PDO 扩展的 SQL 表
- 通过 imap 扩展的 IMAP/POP/NNTP
- 通过 ldap 扩展的 LDAP 和 Active Directory
- 通过自定义适配器的 OAuth
请注意,此包的目的仅用于验证用户凭据。目前它不会处理用户账户的创建和管理,未来可能也不会。这更适合应用层功能,或者至少是一个独立的 Aura 包。
前言
安装
此库需要 PHP 7.2 或更高版本,没有用户空间依赖。
可以通过 Composer 作为 aura/auth 安装和自动加载。
或者,下载一个版本 或克隆此存储库,然后要求或包含其 autoload.php 文件。
质量
要在命令行运行单元测试,请先执行 composer install
,然后在包根目录中执行 vendor/bin/phpunit
。这需要 Composer 作为 composer
可用。
此库尝试遵守 PSR-1、PSR-2 和 PSR-4。如果您注意到合规性疏忽,请通过拉取请求发送补丁。
社区
要提问、提供反馈或与其他 Aura 社区进行交流,请加入我们的 Google Group,关注 @auraphp 或在 Freenode 上与我们聊天。
入门
实例化
要跟踪身份验证状态和相关信息,请使用 AuthFactory 创建一个 Auth 对象。
<?php $auth_factory = new \Aura\Auth\AuthFactory($_COOKIE); $auth = $auth_factory->newInstance(); ?>
您可以使用以下方法从 Auth 实例检索身份验证信息
-
getUserName()
:返回已验证的用户名字符串 -
getUserData()
:返回包含可选任意用户数据的数组 -
getFirstActive()
:返回第一次活动(登录)的 Unix 时间 -
getLastActive()
:返回最近一次活动(通常是当前请求)的 Unix 时间 -
getStatus()
:返回当前身份验证状态的常量。这些常量是-
Status::ANON
-- 匿名/未认证 -
Status::IDLE
-- 已认证会话空闲时间过长 -
Status::EXPIRED
-- 已认证会话的总持续时间过长 -
Status::VALID
-- 已认证且有效
-
-
isAnon()
、isIdle()
、isExpired()
、isValid()
:这些返回基于当前身份验证状态的 true 或 false。
您还可以使用上面提到的 get*()
方法的 set*()
变体来强制 Auth 对象具有您喜欢的任何值。然而,因为这些值存储在 $_SESSION
段中,所以如果没有运行会话,这些值将不会保留。
要保留会话中的值,您可以通过在自己的代码中调用 session_start()
来强制启动会话。或者,使用 Aura.Auth 包的服务来处理身份验证和会话状态管理会更好。
服务
本包提供了三个服务来处理身份验证阶段
-
LoginService 用于登录和启动(或恢复)会话,
-
LogoutService 用于登出并从会话中删除用户名和用户数据(请注意,这 不会 销毁会话),以及
-
ResumeService 用于恢复之前启动的会话。
您可以使用 AuthFactory 创建每个服务。现在,我们将看看如何强制登录和登出;稍后,我们将展示如何让服务使用凭证适配器。
强制登录
您可以通过使用用户名和可选的任意用户数据调用 LoginService 的 forceLogin()
方法来强制将 Auth 对象置于登录状态。
<?php // the authentication status is currently anonymous echo $auth->getStatus(); // ANON // create the login service $login_service = $auth_factory->newLoginService(); // use the service to force $auth to a logged-in state $username = 'boshag'; $userdata = array( 'first_name' => 'Bolivar', 'last_name' => 'Shagnasty', 'email' => 'boshag@example.com', ); $login_service->forceLogin($auth, $username, $userdata); // now the authentication status is valid echo $auth->getStatus(); // VALID ?>
使用 forceLogin()
有以下副作用
-
如果没有已经启动会话,则启动一个新的会话,如果存在则恢复之前的会话
-
重新生成会话 ID
指定的用户名和用户数据将存储在 $_SESSION
段中,并附带 Status::VALID
的身份验证状态。
请注意,forceLogin()
不会检查任何凭证来源。作为应用程序的所有者,您正在强制将 Auth 对象置于登录状态。
强制登出
您可以通过调用 LogoutService 的 forceLogout()
方法来强制将 Auth 对象置于登出状态。
<?php // the authentication status is currently valid echo $auth->getStatus(); // VALID // create the logout service $logout_service = $auth_factory->newLogoutService(); // use the service to force $auth to a logged-out state $logout_service->forceLogout($auth); // now the authentication status is anonymous/invalid echo $auth->getStatus(); // ANON ?>
使用 forceLogout()
有以下副作用
-
从
$_SESSION
段中清除任何现有的用户名和用户数据 -
重新生成会话 ID
请注意,forceLogout()
不会检查任何凭证来源。作为应用程序的所有者,您正在强制将 Auth 对象置于登出状态。
请注意,这也 不会 销毁会话。这是因为您可能需要在会话内存中保留其他东西,例如闪存消息。
恢复会话
当 PHP 请求结束时,PHP 会为您保存 $_SESSION
数据。然而,在下一个请求中,PHP 不会自动为您启动一个新的会话,因此 $_SESSION
不会自动可用。
您可以自己启动一个新的会话来重新填充 $_SESSION
,但这会带来性能开销,如果您实际上不需要会话数据。同样,在之前没有会话(因此没有数据要重新填充到 $_SESSION
)的情况下,可能没有必要启动会话。我们需要的是一种方法,在之前已启动会话时启动会话,但在没有启动会话时避免启动会话。
存在 ResumeService 来解决这个问题。当您在 ResumeService 上调用 resume()
方法时,它会检查 $_COOKIE
以查看是否存在会话cookie
-
如果不存在cookie,它将不会启动会话,并返回到调用代码。这避免了在没有
$_SESSION
数据要填充的情况下启动会话。 -
如果存在cookie,ResumeService 将启动会话,从而重新填充
$_SESSION
。然后,它将根据会话存在的时间更新身份验证状态-
如果会话空闲时间过长(即,自上次请求以来已过去很长时间),ResumeService 将自动将用户登出并返回到调用代码。
-
如果会话已过期(即,总登录时间过长),ResumeService 也将自动将用户登出并返回到调用代码。
-
否则,ResumeService 将更新 Auth 对象的最近活跃时间,并返回到调用代码。
-
通常,您希望在应用程序周期的开始处调用 ResumeService,以便在最早的机会使会话数据可用。
<?php // create the resume service $resume_service = $auth_factory->newResumeService(); // use the service to resume any previously-existing session $resume_service->resume($auth); // $_SESSION has now been repopulated, if a session was started previously, // meaning the $auth object is now populated with its previous values, if any ?>
适配器
强制将 Auth 对象设置为特定状态,当您想要手动控制身份验证状态、用户名、用户数据和其他信息时是可行的。然而,更常见的情况是您想要将用户凭证输入(用户名和密码)与凭证存储进行比对。这就是 Adapter 类发挥作用的地方。
要使用 Adapter 与 Service,您首先需要创建 Adapter,然后将它传递给 AuthFactory 的 new*Service()
方法。
Htpasswd 适配器
实例化
要创建 Apache htpasswd 文件的适配器,调用 AuthFactory 的 newHtpasswdAdapter()
方法,并传递 Apache htpasswd 文件的路径。
<?php $htpasswd_adapter = $auth_factory->newHtpasswdAdapter( '/path/to/accounts.htpasswd' ); ?>
这将自动使用 HtpasswdVerifier 来检查来自 htpasswd 文件的每个用户的 DES、MD5 和 SHA 密码。
服务集成
然后,您可以像这样将 Adapter 传递给每个 Service 工厂方法
<?php $login_service = $auth_factory->newLoginService($htpasswd_adapter); $logout_service = $auth_factory->newLogoutService($htpasswd_adapter); $resume_service = $auth_factory->newResumeService($htpasswd_adapter); ?>
要尝试用户登录,将包含 username
和 password
元素的数组传递给 LoginService 的 login()
方法,并附带 Auth 对象
<?php $login_service->login($auth, array( 'username' => 'boshag', 'password' => '12345' )); ?>
有关 LoginService 习惯用法的更多信息,请参阅服务习惯用法部分。(LogoutService 和 ResumeService 不需要凭证信息。)
IMAP/POP/NNTP 适配器
实例化
要创建 IMAP/POP/NNTP 服务器的适配器,调用 AuthFactory 的 newImapAdapter()
方法,并传递邮箱规范字符串,以及任何适当的选项常量
<?php $imap_adapter = $auth_factory->newImapAdapter( '{mail.example.com:143/imap/secure}', OP_HALFOPEN ); ?>
注意:有关邮箱规范字符串的更多变体,请参阅 imap_open() 文档。
服务集成
然后,您可以像这样将 Adapter 传递给每个 Service 工厂方法
<?php $login_service = $auth_factory->newLoginService($imap_adapter); $logout_service = $auth_factory->newLogoutService($imap_adapter); $resume_service = $auth_factory->newResumeService($imap_adapter); ?>
要尝试用户登录,将包含 username
和 password
元素的数组传递给 LoginService 的 login()
方法,并附带 Auth 对象
<?php $login_service->login($auth, array( 'username' => 'boshag', 'password' => '12345' )); ?>
有关 LoginService 习惯用法的更多信息,请参阅服务习惯用法部分。(LogoutService 和 ResumeService 不需要凭证信息。)
LDAP 适配器
实例化
要创建 LDAP 和 Active Directory 服务器的适配器,调用 AuthFactory 的 newLdapAdapter()
方法,并传递包含唯一名称(DN)格式的字符串的服务器名称
<?php $ldap_adapter = $auth_factory->newLdapAdapter( 'ldaps://ldap.example.com:636', 'ou=Company Name,dc=Department Name,cn=users,uid=%s' ); ?>
注意:用户名将通过 sprintf() 进行转义,然后传递给 DN 格式字符串。完成后的 DN 将在连接后用于绑定到服务器。
服务集成
然后,您可以像这样将 Adapter 传递给每个 Service 工厂方法
<?php $login_service = $auth_factory->newLoginService($ldap_adapter); $logout_service = $auth_factory->newLogoutService($ldap_adapter); $resume_service = $auth_factory->newResumeService($ldap_adapter); ?>
要尝试用户登录,将包含 username
和 password
元素的数组传递给 LoginService 的 login()
方法,并附带 Auth 对象
<?php $login_service->login($auth, array( 'username' => 'boshag', 'password' => '12345' )); ?>
有关 LoginService 习惯用法的更多信息,请参阅服务习惯用法部分。(LogoutService 和 ResumeService 不需要凭证信息。)
PDO 适配器
实例化
要创建与 SQL 表的 PDO 连接的适配器,调用 AuthFactory 的 newPdoAdapter()
方法,并按顺序传递以下参数
-
一个 PDO 连接实例
-
表示数据库中密码哈希方式的指示
-
如果是一个来自 PHP 5.5 及以上版本的
PASSWORD_*
常量,它被视为用于 PasswordVerifier 实例的password_hash()
算法(这是首选方法) -
如果是一个字符串,它被视为用于 HashVerifier 实例的
hash()
算法 -
否则,它预期是一个 VerifierInterface 的实现
-
-
列名数组:第一个元素是用户名列,第二个元素是哈希密码列,额外的列用于从数据库中选择和返回额外的用户信息
-
一个
FROM
规范字符串,用于指示一个或多个表名,以及您希望添加的任何其他JOIN
子句 -
一个可选的
WHERE
条件字符串;使用此字符串添加到适配器构建的SELECT
语句中的额外条件
这是一个使用 MD5 哈希在帐户表中密码的遗留示例
<?php $pdo = new \PDO(...); $hash = new PasswordVerifier('md5'); $cols = array('username', 'md5password'); $from = 'accounts'; $pdo_adapter = $auth_factory->newPdoAdapter($pdo, $hash, $cols, $from); ?>
这是一个使用 bcrypt 替代 md5、从连接的表检索额外的用户信息列并筛选活动帐户的现代、更复杂的示例
<?php $pdo = new \PDO(...); $hash = new PasswordVerifier(PASSWORD_BCRYPT); $cols = array( 'accounts.username', // "AS username" is added by the adapter 'accounts.bcryptpass', // "AS password" is added by the adapter 'accounts.uid AS uid', 'userinfo.email AS email', 'userinfo.uri AS website', 'userinfo.fullname AS display_name', ); $from = 'accounts JOIN profiles ON accounts.uid = profiles.uid'; $where = 'accounts.active = 1'; $pdo_adapter = $auth_factory->newPdoAdapter($pdo, $hash, $cols, $from, $where); ?>
(在成功认证后,额外的信息列将保留在会话数据中。)
服务集成
然后,您可以像这样将 Adapter 传递给每个 Service 工厂方法
<?php $login_service = $auth_factory->newLoginService($pdo_adapter); $logout_service = $auth_factory->newLogoutService($pdo_adapter); $resume_service = $auth_factory->newResumeService($pdo_adapter); ?>
要尝试用户登录,将包含 username
和 password
元素的数组传递给 LoginService 的 login()
方法,并附带 Auth 对象
<?php $login_service->login($auth, array( 'username' => 'boshag', 'password' => '12345' )); ?>
有关 LoginService 习惯用法的更多信息,请参阅服务习惯用法部分。(LogoutService 和 ResumeService 不需要凭证信息。)
自定义适配器
尽管这个包包含多个适配器类,但可能没有一个符合您的需求。
您可能希望扩展现有的适配器以添加登录/注销/恢复行为。或者,您可以通过在所选类上实现适配器接口来创建自己的适配器
<?php use Aura\Auth\Adapter\AdapterInterface; use Aura\Auth\Auth; use Aura\Auth\Status; class CustomAdapter implements AdapterInterface { // AdapterInterface::login() public function login(array $input) { if ($this->isLegit($input)) { $username = ...; $userdata = array(...); $this->updateLoginTime(time()); return array($username, $userdata); } else { throw CustomException('Something went wrong.'); } } // AdapterInterface::logout() public function logout(Auth $auth, $status = Status::ANON) { $this->updateLogoutTime($auth->getUsername(), time()); } // AdapterInterface::resume() public function resume(Auth $auth) { $this->updateActiveTime($auth->getUsername(), time()); } // custom support methods not in the interface protected function isLegit($input) { ... } protected function updateLoginTime($time) { ... } protected function updateActiveTime($time) { ... } protected function updateLogoutTime($time) { ... } } ?>
然后您可以通过AuthFactory方法创建服务时传递自定义适配器的实例
<?php $custom_adapter = new CustomAdapter; $login_service = $auth_factory->newLoginService($custom_adapter); $logout_service = $auth_factory->newLogoutService($custom_adapter); $resume_service = $auth_factory->newResumeService($custom_adapter); ?>
OAuth适配器
如果您希望通过使用OAuth 2.0的第三方服务来处理身份验证,则需要编写一个实现Aura\Auth\Adapter\AdapterInterface
的适配器,并提供您自己的获取访问令牌和用户信息的实现。您的实现可以是您自己编写的,也可以是现有的OAuth2客户端。
以下示例将展示如何使用PHP League的OAuth2客户端创建此适配器。在这个例子中,我们将使用GitHub作为服务提供商。
<?php namespace OAuth2\Adapter; use Aura\Auth\Adapter\AdapterInterface; use Aura\Auth\Exception; use Aura\Auth\Auth; use Aura\Auth\Status; use League\OAuth2\Client\Provider\AbstractProvider; class LeagueOAuth2Adapter implements AdapterInterface { /** * @var \League\OAuth2\Client\Provider\IdentityProvider * The identity provider that the adapter will use */ protected $provider; public function __construct(AbstractProvider $provider) { $this->provider = $provider; } /** * @param $input an input containing the OAuth 2 code * @return array the username and details for the user * @throws \Aura\Auth\Exception * This method must be implemented to fulfill the contract * with AdapterInterface */ public function login(array $input) { if (!isset($input['code'])) { throw new Exception('Authorization code missing.'); } $token = $this->provider->getAccessToken( 'authorization_code', array('code' => $input['code']) ); $details = $this->provider->getResourceOwner($token); $data = [ 'name' => $details->getName(), 'email' => $details->getEmail(), ]; $data['token'] = $token; $username = $data['email']; return [$username, $data]; } /** * @param Auth $auth * Logout method is required to fulfill the contract with AdapterInterface */ public function logout(Auth $auth, $status = Status::ANON) { //nothing to do here } /** * @param Auth $auth * Resume method required to fulfill the contract with AdapterInterface */ public function resume(Auth $auth) { // nothing to do here } } ?>
如代码所示,您的适配器将接受一个客户端作为参数,并使用该客户端来履行\Aura\Auth\Adapter\AdapterInterface协议。此适配器通常用于OAuth2回调过程。本质上,一旦您提供了凭证并与第三方服务(在本例中为GitHub)进行身份验证,您将被重定向回您服务器上的一个脚本,在那里您需要通过将验证码发送回服务来验证您发送了请求。这就是为什么使用好的OAuth2客户端而不是编写自己的代码是一个好主意。以下是OAuth2回调代码的示例。
<?php namespace OAuth2; use Aura\Auth\AuthFactory; use League\OAuth2\Client\Provider\Github; use OAuth2\Adapter\LeagueOAuth2Adapter; use Aura\Auth\Exception; require_once 'vendor/autoload.php'; $auth_factory = new AuthFactory($_COOKIE); $auth = $auth_factory->newInstance(); $github_provider = new Github(array( 'clientId' => 'xxxxxxxxxxxxxxxx', 'clientSecret' => 'xxxxxxxxxxxxxxxxxxxx', 'redirectUri' => 'http://aura.auth.dev/' )); if (!isset($_GET['code'])) { header('Location: ' . $github_provider->getAuthorizationUrl()); exit; } else { $oauth_adapter = new LeagueOAuth2Adapter($github_provider); $login_service = $auth_factory->newLoginService($oauth_adapter); try { // array is the username and an array of info and indicates successful // login $data = $login_service->login($auth, $_GET); } catch (Exception $e) { // handle the exception } } ?>
由于并非每个第三方服务都以相同的方式返回数据,因此Aura尝试处理每种不同的数据集是不合理的。通过编写这段代码,您可以轻松地将Aura Auth应用于您的第三方OAuth2服务。
服务惯用语
恢复会话
以下是恢复现有会话所需的代码示例。请注意,echo
语句的目的是解释resume()
调用的不同结果状态,可以根据您认为合适的逻辑进行替换。例如,您可能希望在会话空闲或过期时重定向到登录页面。
<?php $auth = $auth_factory->newInstance(); $resume_service = $auth_factory->newResumeService(...); $resume_service->resume($auth); switch (true) { case $auth->isAnon(): echo "You are not logged in."; break; case $auth->isIdle(): echo "Your session was idle for too long. Please log in again."; break; case $auth->isExpired(): echo "Your session has expired. Please log in again."; break; case $auth->isValid(): echo "You are still logged in."; break; default: echo "You have an unknown status."; break; } ?>
注意:您可能希望使用依赖注入容器(例如Aura.Di)手动创建Auth和ResumeService对象,以在您的应用程序中保留它们供共享使用。
登录
以下是实现登录所需的代码示例。请注意,echo
和$log
语句的目的是解释login()
调用的不同结果状态,可以根据您认为合适的逻辑进行替换;特别是,您可能不希望暴露失败的精确性质,以帮助减轻暴力尝试。
<?php class InvalidLoginException extends Exception {} $auth = $auth_factory->newInstance(); $login_service = $auth_factory->newLoginService(...); try { $login_service->login($auth, array( 'username' => $_POST['username'], 'password' => $_POST['password'], ); echo "You are now logged into a new session."; } catch (\Aura\Auth\Exception\UsernameMissing $e) { $log->notice("The 'username' field is missing or empty."); throw new InvalidLoginException(); } catch (\Aura\Auth\Exception\PasswordMissing $e) { $log->notice("The 'password' field is missing or empty."); throw new InvalidLoginException(); } catch (\Aura\Auth\Exception\UsernameNotFound $e) { $log->warning("The username you entered was not found."); throw new InvalidLoginException(); } catch (\Aura\Auth\Exception\MultipleMatches $e) { $log->warning("There is more than one account with that username."); throw new InvalidLoginException(); } catch (\Aura\Auth\Exception\PasswordIncorrect $e) { $log->notice("The password you entered was incorrect."); throw new InvalidLoginException(); } catch (\Aura\Auth\Exception\ConnectionFailed $e) { $log->notice("Cound not connect to IMAP or LDAP server."); $log->info("This could be because the username or password was wrong,"); $log->info("or because the the connect operation itself failed in some way. "); $log->info($e->getMessage()); throw new InvalidLoginException(); } catch (\Aura\Auth\Exception\BindFailed $e) { $log->notice("Cound not bind to LDAP server."); $log->info("This could be because the username or password was wrong,"); $log->info("or because the the bind operation itself failed in some way. "); $log->info($e->getMessage()); throw new InvalidLoginException(); } catch (InvalidLoginException $e) { echo "Invalid login details. Please try again."; } ?>
注意:您可能希望使用依赖注入容器(例如Aura.Di)手动创建Auth和LoginService对象,以在您的应用程序中保留它们供共享使用。
或者,您可能希望使用HTTP Authorization: Basic
头部的凭据而不是使用$_POST
或其他与表单相关的输入。在Apache mod_php
上,您可能使用自动填充的$_SERVER['PHP_AUTH_*']
值
<?php $authorization_basic = function () { return array( isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : null, isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : null, ); } list($username, $password) = $authorization_basic(); $login_service->login($auth, array( 'username' => $username, 'password' => $password, )); ?>
在其他服务器上,您可能需要从Authorization: Basic
头部本身提取凭据
<?php $authorization_basic = function () { $header = isset($_SERVER['HTTP_AUTHORIZATION']) ? $_SERVER['HTTP_AUTHORIZATION'] : ''; if (strtolower(substr($header, 0, 6)) !== 'basic ') { return array(null, null); } $encoded = substr($header, 6); $decoded = base64_decode($encoded); return explode(':', $decoded); } list($username, $password) = $authorization_basic(); $login_service->login($auth, array( 'username' => $username, 'password' => $password, )); ?>
注销
这是实现注销所需的代码示例。请注意,echo
语句旨在解释logout()
调用的不同结果状态,可以根据需要替换为任何逻辑。
<?php $auth = $auth_factory->newInstance(); $logout_service = $auth_factory->newLogoutService(...); $logout_service->logout($auth); if ($auth->isAnon()) { echo "You are now logged out."; } else { echo "Something went wrong; you are still logged in."; } ?>
注意:您可以使用依赖注入容器(例如Aura.Di)而不是手动创建Auth和LogoutService对象,以在整个应用程序中保持它们以供共享使用。
自定义服务
您不受此包提供的登录、注销和恢复服务的限制。但是,如果您构建了自己的服务或扩展了提供的某个服务,您将不得不手动实例化该自定义服务对象,而不是使用AuthFactory。这可能会很繁琐,但并不困难,尤其是在使用Aura.Di等依赖注入容器系统时。
会话管理
Service对象使用Session对象来启动会话并重新生成会话ID。(注意,它们不会销毁会话。)Session对象使用原生PHP的session_*()
函数来管理会话。
自定义会话
如果您希望使用其他方式来管理会话,可以在您选择的对象上实现SessionInterface。一种方法是包装框架特定的会话对象,并将SessionInterface方法代理到包装对象。
<?php use Aura\Auth\Session\SessionInterface; class CustomSession implements SessionInterface { protected $fwsession; public function __construct(FrameworkSession $fwsession) { $this->fwsession = $fwsession; } public function start() { return $this->fwsession->startSession(); } public function resume() { if ($this->fwsession->isAlreadyStarted()) { return true; } if ($this->fwsession->canBeRestarted()) { return $this->fwsession->restartSession(); } return false; } public function regenerateId() { return $this->fwsession->regenerateSessionId(); } } ?>
然后,将自定义会话对象传递给AuthFactory实例化。
<?php use Aura\Auth\AuthFactory; $custom_session = new CustomSession(new FrameworkSession); $auth_factory = new AuthFactory($_COOKIE, $custom_session); ?>
工厂将把您的自定义会话对象传递到需要的地方。
不使用会话进行工作
在某些情况下,例如与API一起使用,其中每个请求都提供了凭据,避免使用会话可能会有所帮助。在这种情况下,将NullSession和NullSegment传递给AuthFactory。
<?php use Aura\Auth\AuthFactory; use Aura\Auth\Session\NullSession; use Aura\Auth\Session\NullSegment; $null_session = new NullSession; $null_segment = new NullSegment; $auth_factory = new AuthFactory($_COOKIE, $null_session, $null_segment); ?>
对于NullSession,永远不会启动会话,也不会创建或重新生成会话ID。同样,由于在先前的请求结束时从未保存,永远不会恢复会话。最后,PHP永远不会创建会话cookie以发送到响应中。
同样,NullSegment将认证信息保留在对象属性中,而不是在$_SESSION
段中。与仅在$_SESSION
存在时保留数据的正常Segment不同,NullSegment将始终保留设置到其中的数据。当请求结束时,NullSegment中保留的所有信息都将消失。
使用NullSession和NullSegment时,您必须在每个请求上通过LoginService的login()
或forceLogin()
方法检查凭据,这反过来会在Segment中保留认证信息。在API情况下,这通常比管理持续会话更可取。
注意:在API情况下,凭据可能是一个API令牌,或者作为HTTP基本或摘要认证头传递。将这些传递给您选择的适配器。
DI配置
以下是有关通过Aura.Di配置Aura.Auth的一些提示。
Aura\Auth\Adapter\HtpasswdAdapter
<?php $di->params['Aura\Auth\Adapter\HtpasswdAdapter'] = array( 'file' => '/path/to/htpasswdfile', ); ?>
Aura\Auth\Adapter\ImapAdapter
<?php $di->params['Aura\Auth\Adapter\ImapAdapter'] = array( 'mailbox' => '{mail.example.com:143/imap/secure}', ); ?>
Aura\Auth\Adapter\LdapAdapter
<?php $di->params['Aura\Auth\Adapter\LdapAdapter'] = array( 'server' => 'ldaps://ldap.example.com:636', 'dnformat' => 'ou=Company Name,dc=Department Name,cn=users,uid=%s', ); ?>
Aura\Auth\Adapter\PdoAdapter
<?php $di->params['Aura\Auth\Adapter\PdoAdapter'] = array( 'pdo' => $di->lazyGet('your_pdo_connection_service'), 'cols' => array( 'username_column', 'password_column', ), 'from' => 'users_table', 'where' => '', ); ?>