用户symfony2与userApp.io中的用户身份验证
> UserApp.io是一种方便的用户管理工具和API。它提供了一个Web界面来处理用户帐户(以及这涉及的许多功能)和一个API,将它们吸引到您自己的Web应用程序中。此服务的目的是通过不必在自己的服务器上担心这一点,使管理用户身份验证变得更加容易,更安全。

>它具有许多编程语言和框架的SDK和各种包装纸,而且价格负担得起。是的,它带有一个价格,但是您可以自由地开始使用很多事情要玩。我建议查看他们的功能页面以获取更多信息。另外,创建一个帐户和实验以创建用户,在其配置文件中添加属性等非常容易,因此我建议您还要检查一下,如果还没有。
在本文中,我们将研究如何实现利用UserApp.io的Symfony2身份验证机制。我们编写的代码也可以在我创建的这个小库(当前在开发中)中找到,您可以尝试。要将其安装在您的Symfony应用中,只需按照Github上的说明进行操作即可。钥匙要点
- UserApp.io提供了一个全面的用户管理API,使其更简单,更安全地处理无需服务器端问题的用户身份验证。
-
通过PHP库来促进与UserApp.io集成的Symfony2集成,该库可以通过Composer易于安装,并且可以在Symfony的服务框架中配置。
> >自定义类,例如形式身份验证者,用户提供商和注销处理程序,对于在Symfony2中利用UserApp.io至关重要,实现了无缝的身份验证过程。
- symfony2中的表单Authenticator类处理用户登录尝试,基于UserApp.io的响应创建和身份验证令牌。
>
Symfony2中的用户提供商与用户App.io进行交互以获取用户详细信息并将其转换为与Symfony兼容的用户对象,有效地处理角色和权限。 - > 登记用户涉及一个自定义注销处理程序类,该类与UserApp.io进行交互,以确保还可以从服务中记录用户,从而保持跨平台的一致性。
- dependecies
- 为了与UserApp.io服务进行通信,我们将使用其PHP库。确保您按照其GitHub页面上的指示在Symfony应用程序的Composer.json文件中需要此。
- 身份验证类
- >一种表单身份验证者类,用于使用UserApp.io API 执行身份验证
- >用于代表我们的用户的自定义用户类,并从API 中收集的信息
- >用户提供商类用于检索用户并将其转换为我们用户类的对象 >
- a代表代表对称身份验证令牌 的代币类
- >注销处理程序类,负责从UserApp.io服务中登录。 如果UserApp.io用户没有任何权限设置(我们将转换为Symfony角色),我们可以投掷一个简单的异常类别
- >创建这些类后,我们将其中一些将其声明为服务,并在Symfony安全系统中使用它们。
形式authenticator
首先,我们将创建最重要的类,即验证符(在我们最佳实践的AppBundle的安全性/文件夹中)。这是代码,然后将其解释:
>如您所见,我们正在实现SimpleFormauthenticatorInterface,因此具有3种方法和一个构造函数。后者作为实例化的UserApp.io客户端(使用服务容器传递,但在一分钟内通过此信息)。 当用户试图使用应用程序登录和身份验证时,Symfony使用了此类。发生的第一件事是称为createToken()。此方法需要返回结合提交的用户名和密码的身份验证令牌。在我们的情况下,这将是我们将在稍后定义的UserAppToken类的一个实例。
<span><span><?php </span></span><span> </span><span><span>/** </span></span><span><span> * <span>@file AppBundle\Security\UserAppAuthenticator.php </span></span></span><span><span> */ </span></span><span> </span><span><span>namespace AppBundle<span>\Security</span>; </span></span><span> </span><span><span>use Symfony<span>\Component\HttpFoundation\Request</span>; </span></span><span><span>use Symfony<span>\Component\Security\Core\Authentication\SimpleFormAuthenticatorInterface</span>; </span></span><span><span>use Symfony<span>\Component\Security\Core\Authentication\Token\TokenInterface</span>; </span></span><span><span>use Symfony<span>\Component\Security\Core\Exception\AuthenticationException</span>; </span></span><span><span>use Symfony<span>\Component\Security\Core\User\UserProviderInterface</span>; </span></span><span><span>use UserApp<span>\API</span> as UserApp; </span></span><span><span>use UserApp<span>\Exceptions\ServiceException</span>; </span></span><span> </span><span><span>class UserAppAuthenticator implements SimpleFormAuthenticatorInterface </span></span><span><span>{ </span></span><span> </span><span> <span>/** </span></span><span><span> * <span>@var UserApp </span></span></span><span><span> */ </span></span><span> <span>private $userAppClient; </span></span><span> </span><span> <span>public function __construct(UserApp $userAppClient) { </span></span><span> <span>$this->userAppClient = $userAppClient; </span></span><span> <span>} </span></span><span> </span><span> <span>/** </span></span><span><span> * <span>{@inheritdoc} </span></span></span><span><span> */ </span></span><span> <span>public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey) </span></span><span> <span>{ </span></span><span> </span><span> <span>try { </span></span><span> <span>$login = $this->userAppClient->user->login(array( </span></span><span> <span>"login" => $token->getUsername(), </span></span><span> <span>"password" => $token->getCredentials(), </span></span><span> <span>) </span></span><span> <span>); </span></span><span> </span><span> <span>// Load user from provider based on id </span></span><span> <span>$user = $userProvider->loadUserByLoginInfo($login); </span></span><span> <span>} catch(ServiceException $exception) { </span></span><span> <span>if ($exception->getErrorCode() == 'INVALID_ARGUMENT_LOGIN' || $exception->getErrorCode() == 'INVALID_ARGUMENT_PASSWORD') { </span></span><span> <span>throw new AuthenticationException('Invalid username or password'); </span></span><span> <span>} </span></span><span> <span>if ($exception->getErrorCode() == 'INVALID_ARGUMENT_APP_ID') { </span></span><span> <span>throw new AuthenticationException('Invalid app ID'); </span></span><span> <span>} </span></span><span> <span>} </span></span><span> <span>return new UserAppToken( </span></span><span> <span>$user, </span></span><span> <span>$user->getToken(), </span></span><span> <span>$providerKey, </span></span><span> <span>$user->getRoles() </span></span><span> <span>); </span></span><span> <span>} </span></span><span> </span><span> <span>/** </span></span><span><span> * <span>{@inheritdoc} </span></span></span><span><span> */ </span></span><span> <span>public function supportsToken(TokenInterface $token, $providerKey) </span></span><span> <span>{ </span></span><span> <span>return $token instanceof UserAppToken </span></span><span> <span>&& $token->getProviderKey() === $providerKey; </span></span><span> <span>} </span></span><span> </span><span> <span>/** </span></span><span><span> * <span>{@inheritdoc} </span></span></span><span><span> */ </span></span><span> <span>public function createToken(Request $request, $username, $password, $providerKey) </span></span><span> <span>{ </span></span><span> <span>return new UserAppToken($username, $password, $providerKey); </span></span><span> <span>} </span></span><span><span>}</span></span>
>
>最后,AuthentIcateToken()被调用,并尝试检查令牌中的凭据是否有效。在此处,并使用userApp.io php库,如果失败,我们尝试登录或投掷Symfony身份验证例外。但是,如果身份验证成功,则负责的用户提供商将用于建立我们的用户对象,然后根据后者创建和返回另一个令牌对象。>我们将在快速创建简单的UserAppToken类后立即编写我们的用户提供商。
>令牌类
如您所见,这只是命名更准确的用户名Passpasswordtoken类的扩展(因为我们存储一个令牌而不是密码)。
>用户提供商接下来,让我们看看身份验证器如何与用户提供商合作,所以也该创建后者了:
<span><span><?php </span></span><span> </span><span><span>/** </span></span><span><span> * <span>@file AppBundle\Security\UserAppToken.php </span></span></span><span><span> */ </span></span><span> </span><span><span>namespace AppBundle<span>\Security</span>; </span></span><span> </span><span><span>use Symfony<span>\Component\Security\Core\Authentication\Token\UsernamePasswordToken</span>; </span></span><span> </span><span><span>class UserAppToken extends UsernamePasswordToken { </span></span><span> </span><span><span>}</span></span>
- > loaduserbyusername() - 我们现在不需要它,因为我们不需要它 >
- refrreshuser() - 在每个身份验证的请求 上被调用
- supportsClass() - 确定此用户提供商是否与我们(尚未创建的)用户类一起工作。
异常类是默认php异常的简单扩展名:
>再次回到我们的身份验证器,我们看到,如果使用UserApp.io成功验证,则用户提供商构建了一个用户提供商,其中包含用户上的所有必要信息。拥有此对象,我们需要将其添加到UserApptoken类的新实例中并返回。
<span><span><?php </span></span><span> </span><span><span>/** </span></span><span><span> * <span>@file AppBundle\Security\UserAppAuthenticator.php </span></span></span><span><span> */ </span></span><span> </span><span><span>namespace AppBundle<span>\Security</span>; </span></span><span> </span><span><span>use Symfony<span>\Component\HttpFoundation\Request</span>; </span></span><span><span>use Symfony<span>\Component\Security\Core\Authentication\SimpleFormAuthenticatorInterface</span>; </span></span><span><span>use Symfony<span>\Component\Security\Core\Authentication\Token\TokenInterface</span>; </span></span><span><span>use Symfony<span>\Component\Security\Core\Exception\AuthenticationException</span>; </span></span><span><span>use Symfony<span>\Component\Security\Core\User\UserProviderInterface</span>; </span></span><span><span>use UserApp<span>\API</span> as UserApp; </span></span><span><span>use UserApp<span>\Exceptions\ServiceException</span>; </span></span><span> </span><span><span>class UserAppAuthenticator implements SimpleFormAuthenticatorInterface </span></span><span><span>{ </span></span><span> </span><span> <span>/** </span></span><span><span> * <span>@var UserApp </span></span></span><span><span> */ </span></span><span> <span>private $userAppClient; </span></span><span> </span><span> <span>public function __construct(UserApp $userAppClient) { </span></span><span> <span>$this->userAppClient = $userAppClient; </span></span><span> <span>} </span></span><span> </span><span> <span>/** </span></span><span><span> * <span>{@inheritdoc} </span></span></span><span><span> */ </span></span><span> <span>public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey) </span></span><span> <span>{ </span></span><span> </span><span> <span>try { </span></span><span> <span>$login = $this->userAppClient->user->login(array( </span></span><span> <span>"login" => $token->getUsername(), </span></span><span> <span>"password" => $token->getCredentials(), </span></span><span> <span>) </span></span><span> <span>); </span></span><span> </span><span> <span>// Load user from provider based on id </span></span><span> <span>$user = $userProvider->loadUserByLoginInfo($login); </span></span><span> <span>} catch(ServiceException $exception) { </span></span><span> <span>if ($exception->getErrorCode() == 'INVALID_ARGUMENT_LOGIN' || $exception->getErrorCode() == 'INVALID_ARGUMENT_PASSWORD') { </span></span><span> <span>throw new AuthenticationException('Invalid username or password'); </span></span><span> <span>} </span></span><span> <span>if ($exception->getErrorCode() == 'INVALID_ARGUMENT_APP_ID') { </span></span><span> <span>throw new AuthenticationException('Invalid app ID'); </span></span><span> <span>} </span></span><span> <span>} </span></span><span> <span>return new UserAppToken( </span></span><span> <span>$user, </span></span><span> <span>$user->getToken(), </span></span><span> <span>$providerKey, </span></span><span> <span>$user->getRoles() </span></span><span> <span>); </span></span><span> <span>} </span></span><span> </span><span> <span>/** </span></span><span><span> * <span>{@inheritdoc} </span></span></span><span><span> */ </span></span><span> <span>public function supportsToken(TokenInterface $token, $providerKey) </span></span><span> <span>{ </span></span><span> <span>return $token instanceof UserAppToken </span></span><span> <span>&& $token->getProviderKey() === $providerKey; </span></span><span> <span>} </span></span><span> </span><span> <span>/** </span></span><span><span> * <span>{@inheritdoc} </span></span></span><span><span> */ </span></span><span> <span>public function createToken(Request $request, $username, $password, $providerKey) </span></span><span> <span>{ </span></span><span> <span>return new UserAppToken($username, $password, $providerKey); </span></span><span> <span>} </span></span><span><span>}</span></span>
基本上,这是从用户试图登录的那一刻发生的:
我们使用提交的凭据(createToken())
创建一个令牌- 我们尝试在此令牌中验证凭据,如果我们失败
- 我们创建一个包含用户对象的新令牌和其他信息,如果身份验证成功
- > 我们返回Symfony然后将其用于将用户存储在会话中的代币。
- 用户提供商上的RefrReshuser()方法也非常重要。此方法负责检索每个身份验证的页面刷新中当前登录的用户的新实例。因此,每当身份验证的用户转到防火墙内的任何页面时,此方法就会触发。关键是将用户对象与同时可能发生的存储器发生任何更改进行补充。
- 显然,我们需要将API呼叫保持在最低限度,但这是一个很好的机会,可以通过发送心跳请求来增加UserApp.io的身份验证时间。默认情况下(但可配置),每个身份验证的用户令牌均有效60分钟,但是通过发送心跳请求,将其扩展到20分钟。
- 如果令牌同时在UserApp.io中到期,我们会得到一个有价值的例外的Invalid_credentials,因此通过抛出Symfony AuthenticationException,我们也将用户登录Symfony。
- >尽管使心跳请求变得尽可能便宜(这意味着未检索实际的用户数据),但用户锁定状态的确以例外形式回传递。因此,我们可以借此机会并标记我们的用户对象锁定。然后,可以在应用程序中使用锁定状态,例如,通过对其进行检查并拒绝使用用户锁定的各个部分的访问。 >
如果您需要,可以在此处使用UserApp.io的数据更新用户对象,但我发现在大多数用例中,这并没有多大意义。当用户下一次注销并返回时,可以更新数据。但是根据需求,这可以在这里轻松完成。虽然请记住性能的影响和许多API调用的成本。
基本上,这是我们身份验证逻辑的关键。>用户类
>我们还创建以前一直在谈论的UserAppuser类:
>这里没有什么特别的,我们只是映射来自UserApp.io的一些数据并实现接口所需的一些方法。此外,我们添加了锁定/解锁的旗手。
<span><span><?php </span></span><span> </span><span><span>/** </span></span><span><span> * <span>@file AppBundle\Security\UserAppAuthenticator.php </span></span></span><span><span> */ </span></span><span> </span><span><span>namespace AppBundle<span>\Security</span>; </span></span><span> </span><span><span>use Symfony<span>\Component\HttpFoundation\Request</span>; </span></span><span><span>use Symfony<span>\Component\Security\Core\Authentication\SimpleFormAuthenticatorInterface</span>; </span></span><span><span>use Symfony<span>\Component\Security\Core\Authentication\Token\TokenInterface</span>; </span></span><span><span>use Symfony<span>\Component\Security\Core\Exception\AuthenticationException</span>; </span></span><span><span>use Symfony<span>\Component\Security\Core\User\UserProviderInterface</span>; </span></span><span><span>use UserApp<span>\API</span> as UserApp; </span></span><span><span>use UserApp<span>\Exceptions\ServiceException</span>; </span></span><span> </span><span><span>class UserAppAuthenticator implements SimpleFormAuthenticatorInterface </span></span><span><span>{ </span></span><span> </span><span> <span>/** </span></span><span><span> * <span>@var UserApp </span></span></span><span><span> */ </span></span><span> <span>private $userAppClient; </span></span><span> </span><span> <span>public function __construct(UserApp $userAppClient) { </span></span><span> <span>$this->userAppClient = $userAppClient; </span></span><span> <span>} </span></span><span> </span><span> <span>/** </span></span><span><span> * <span>{@inheritdoc} </span></span></span><span><span> */ </span></span><span> <span>public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey) </span></span><span> <span>{ </span></span><span> </span><span> <span>try { </span></span><span> <span>$login = $this->userAppClient->user->login(array( </span></span><span> <span>"login" => $token->getUsername(), </span></span><span> <span>"password" => $token->getCredentials(), </span></span><span> <span>) </span></span><span> <span>); </span></span><span> </span><span> <span>// Load user from provider based on id </span></span><span> <span>$user = $userProvider->loadUserByLoginInfo($login); </span></span><span> <span>} catch(ServiceException $exception) { </span></span><span> <span>if ($exception->getErrorCode() == 'INVALID_ARGUMENT_LOGIN' || $exception->getErrorCode() == 'INVALID_ARGUMENT_PASSWORD') { </span></span><span> <span>throw new AuthenticationException('Invalid username or password'); </span></span><span> <span>} </span></span><span> <span>if ($exception->getErrorCode() == 'INVALID_ARGUMENT_APP_ID') { </span></span><span> <span>throw new AuthenticationException('Invalid app ID'); </span></span><span> <span>} </span></span><span> <span>} </span></span><span> <span>return new UserAppToken( </span></span><span> <span>$user, </span></span><span> <span>$user->getToken(), </span></span><span> <span>$providerKey, </span></span><span> <span>$user->getRoles() </span></span><span> <span>); </span></span><span> <span>} </span></span><span> </span><span> <span>/** </span></span><span><span> * <span>{@inheritdoc} </span></span></span><span><span> */ </span></span><span> <span>public function supportsToken(TokenInterface $token, $providerKey) </span></span><span> <span>{ </span></span><span> <span>return $token instanceof UserAppToken </span></span><span> <span>&& $token->getProviderKey() === $providerKey; </span></span><span> <span>} </span></span><span> </span><span> <span>/** </span></span><span><span> * <span>{@inheritdoc} </span></span></span><span><span> */ </span></span><span> <span>public function createToken(Request $request, $username, $password, $providerKey) </span></span><span> <span>{ </span></span><span> <span>return new UserAppToken($username, $password, $providerKey); </span></span><span> <span>} </span></span><span><span>}</span></span>
登录
>我们需要创建的最后一类是处理用户从symfony登录时从UserApp.io中登录用户的类别。
>再次在这里注入userApp.io php客户端,并且由于我们实现了LogouthandlerInterface,因此我们需要具有logout()方法。我们要做的就是从UserApp.io登录用户。
<span><span><?php </span></span><span> </span><span><span>/** </span></span><span><span> * <span>@file AppBundle\Security\UserAppToken.php </span></span></span><span><span> */ </span></span><span> </span><span><span>namespace AppBundle<span>\Security</span>; </span></span><span> </span><span><span>use Symfony<span>\Component\Security\Core\Authentication\Token\UsernamePasswordToken</span>; </span></span><span> </span><span><span>class UserAppToken extends UsernamePasswordToken { </span></span><span> </span><span><span>}</span></span>
>现在我们有了我们的课程,现在该将它们声明为服务并在我们的身份验证系统中使用。这是我们的基于YML的服务声明:
第一个是我们以参数的引用形式在应用程序ID中传递给我们的应用ID的UserApp.io PHP库。您需要使用UserApp.io应用ID的参数称为userApp_id。
<span><span><?php </span></span><span> </span><span><span>/** </span></span><span><span> * <span>@file AppBundle\Security\UserAppProvider.php </span></span></span><span><span> */ </span></span><span> </span><span><span>namespace AppBundle<span>\Security</span>; </span></span><span> </span><span><span>use Symfony<span>\Component\Security\Core\Exception\AuthenticationException</span>; </span></span><span><span>use Symfony<span>\Component\Security\Core\Exception\UsernameNotFoundException</span>; </span></span><span><span>use Symfony<span>\Component\Security\Core\User\UserProviderInterface</span>; </span></span><span><span>use Symfony<span>\Component\Security\Core\User\UserInterface</span>; </span></span><span><span>use Symfony<span>\Component\Security\Core\Exception\UnsupportedUserException</span>; </span></span><span><span>use UserApp<span>\API</span> as UserApp; </span></span><span><span>use UserApp<span>\Exceptions\ServiceException</span>; </span></span><span><span>use AppBundle<span>\Security\Exception\NoUserRoleException</span>; </span></span><span><span>use AppBundle<span>\Security\UserAppUser</span>; </span></span><span> </span><span><span>class UserAppProvider implements UserProviderInterface </span></span><span><span>{ </span></span><span> <span>/** </span></span><span><span> * <span>@var UserApp </span></span></span><span><span> */ </span></span><span> <span>private $userAppClient; </span></span><span> </span><span> <span>public function __construct(UserApp $userAppClient) { </span></span><span> <span>$this->userAppClient = $userAppClient; </span></span><span> <span>} </span></span><span> </span><span> <span>/** </span></span><span><span> * <span>{@inheritdoc} </span></span></span><span><span> */ </span></span><span> <span>public function loadUserByUsername($username) </span></span><span> <span>{ </span></span><span> <span>// Empty for now </span></span><span> <span>} </span></span><span> </span><span> <span>/** </span></span><span><span> * <span>{@inheritdoc} </span></span></span><span><span> */ </span></span><span> <span>public function refreshUser(UserInterface $user) </span></span><span> <span>{ </span></span><span> <span>if (!$user instanceof UserAppUser) { </span></span><span> <span>throw new UnsupportedUserException( </span></span><span> <span>sprintf('Instances of "%s" are not supported.', get_class($user)) </span></span><span> <span>); </span></span><span> <span>} </span></span><span> </span><span> <span>try { </span></span><span> <span>$api = $this->userAppClient; </span></span><span> <span>$api->setOption('token', $user->getToken()); </span></span><span> <span>$api->token->heartbeat(); </span></span><span> <span>$user->unlock(); </span></span><span> <span>} </span></span><span> <span>catch (ServiceException $exception) { </span></span><span> <span>if ($exception->getErrorCode() == 'INVALID_CREDENTIALS') { </span></span><span> <span>throw new AuthenticationException('Invalid credentials'); </span></span><span> <span>} </span></span><span> <span>if ($exception->getErrorCode() == 'AUTHORIZATION_USER_LOCKED') { </span></span><span> <span>$user->lock(); </span></span><span> <span>} </span></span><span> <span>} </span></span><span> </span><span> <span>return $user; </span></span><span> <span>} </span></span><span> </span><span> <span>/** </span></span><span><span> * <span>{@inheritdoc} </span></span></span><span><span> */ </span></span><span> <span>public function supportsClass($class) </span></span><span> <span>{ </span></span><span> <span>return $class === 'AppBundle\Security\UserAppUser'; </span></span><span> <span>} </span></span><span> </span><span> <span>/** </span></span><span><span> * </span></span><span><span> * Loads a user from UserApp.io based on a successful login response. </span></span><span><span> * </span></span><span><span> * <span>@param $login </span></span></span><span><span> * <span>@return UserAppUser </span></span></span><span><span> * <span>@throws NoUserRoleException </span></span></span><span><span> */ </span></span><span> <span>public function loadUserByLoginInfo($login) { </span></span><span> </span><span> <span>try { </span></span><span> <span>$api = $this->userAppClient; </span></span><span> <span>$api->setOption('token', $login->token); </span></span><span> <span>$users = $api->user->get(); </span></span><span> <span>} catch(ServiceException $exception) { </span></span><span> <span>if ($exception->getErrorCode() == 'INVALID_ARGUMENT_USER_ID') { </span></span><span> <span>throw new UsernameNotFoundException(sprintf('User with the id "%s" not found.', $login->user_id)); </span></span><span> <span>} </span></span><span> <span>} </span></span><span> </span><span> <span>if (!empty($users)) { </span></span><span> <span>return $this->userFromUserApp($users[0], $login->token); </span></span><span> <span>} </span></span><span> <span>} </span></span><span> </span><span> <span>/** </span></span><span><span> * Creates a UserAppUser from a user response from UserApp.io </span></span><span><span> * </span></span><span><span> * <span>@param $user </span></span></span><span><span> * <span>@param $token </span></span></span><span><span> * <span>@return UserAppUser </span></span></span><span><span> * <span>@throws NoUserRoleException </span></span></span><span><span> */ </span></span><span> <span>private function userFromUserApp($user, $token) { </span></span><span> </span><span> <span>$roles = $this->extractRolesFromPermissions($user); </span></span><span> </span><span> <span>$options = array( </span></span><span> <span>'id' => $user->user_id, </span></span><span> <span>'username' => $user->login, </span></span><span> <span>'token' => $token, </span></span><span> <span>'firstName' => $user->first_name, </span></span><span> <span>'lastName' => $user->last_name, </span></span><span> <span>'email' => $user->email, </span></span><span> <span>'roles' => $roles, </span></span><span> <span>'properties' => $user->properties, </span></span><span> <span>'features' => $user->features, </span></span><span> <span>'permissions' => $user->permissions, </span></span><span> <span>'created' => $user->created_at, </span></span><span> <span>'locked' => !empty($user->locks), </span></span><span> <span>'last_logged_in' => $user->last_login_at, </span></span><span> <span>'last_heartbeat' => time(), </span></span><span> <span>); </span></span><span> </span><span> <span>return new UserAppUser($options); </span></span><span> <span>} </span></span><span> </span><span> <span>/** </span></span><span><span> * Extracts the roles from the permissions list of a user </span></span><span><span> * </span></span><span><span> * <span>@param $user </span></span></span><span><span> * <span>@return <span>array</span> </span></span></span><span><span> * <span>@throws NoUserRoleException </span></span></span><span><span> */ </span></span><span> <span>private function extractRolesFromPermissions($user) { </span></span><span> <span>$permissions = get_object_vars($user->permissions); </span></span><span> <span>if (empty($permissions)) { </span></span><span> <span>throw new NoUserRoleException('There are no roles set up for your users.'); </span></span><span> <span>} </span></span><span> <span>$roles = array(); </span></span><span> <span>foreach ($permissions as $role => $permission) { </span></span><span> <span>if ($permission->value === TRUE) { </span></span><span> <span>$roles[] = $role; </span></span><span> <span>} </span></span><span> <span>} </span></span><span> </span><span> <span>if (empty($roles)) { </span></span><span> <span>throw new NoUserRoleException('This user has no roles enabled.'); </span></span><span> <span>} </span></span><span> </span><span> <span>return $roles; </span></span><span> <span>} </span></span><span><span>}</span></span>
接下来,是时候在我们的安全系统中使用这些服务了,因此编辑Security.yml文件并执行以下操作:
在提供者密钥下
,添加以下内容:
- 在这里,我们指定我们的应用程序也具有此用户提供商,因此可以使用它。
- >
在防火墙钥匙下,添加以下内容:
>
<span><span><?php </span></span><span> </span><span><span>/** </span></span><span><span> * <span>@file AppBundle\Security\UserAppAuthenticator.php </span></span></span><span><span> */ </span></span><span> </span><span><span>namespace AppBundle<span>\Security</span>; </span></span><span> </span><span><span>use Symfony<span>\Component\HttpFoundation\Request</span>; </span></span><span><span>use Symfony<span>\Component\Security\Core\Authentication\SimpleFormAuthenticatorInterface</span>; </span></span><span><span>use Symfony<span>\Component\Security\Core\Authentication\Token\TokenInterface</span>; </span></span><span><span>use Symfony<span>\Component\Security\Core\Exception\AuthenticationException</span>; </span></span><span><span>use Symfony<span>\Component\Security\Core\User\UserProviderInterface</span>; </span></span><span><span>use UserApp<span>\API</span> as UserApp; </span></span><span><span>use UserApp<span>\Exceptions\ServiceException</span>; </span></span><span> </span><span><span>class UserAppAuthenticator implements SimpleFormAuthenticatorInterface </span></span><span><span>{ </span></span><span> </span><span> <span>/** </span></span><span><span> * <span>@var UserApp </span></span></span><span><span> */ </span></span><span> <span>private $userAppClient; </span></span><span> </span><span> <span>public function __construct(UserApp $userAppClient) { </span></span><span> <span>$this->userAppClient = $userAppClient; </span></span><span> <span>} </span></span><span> </span><span> <span>/** </span></span><span><span> * <span>{@inheritdoc} </span></span></span><span><span> */ </span></span><span> <span>public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey) </span></span><span> <span>{ </span></span><span> </span><span> <span>try { </span></span><span> <span>$login = $this->userAppClient->user->login(array( </span></span><span> <span>"login" => $token->getUsername(), </span></span><span> <span>"password" => $token->getCredentials(), </span></span><span> <span>) </span></span><span> <span>); </span></span><span> </span><span> <span>// Load user from provider based on id </span></span><span> <span>$user = $userProvider->loadUserByLoginInfo($login); </span></span><span> <span>} catch(ServiceException $exception) { </span></span><span> <span>if ($exception->getErrorCode() == 'INVALID_ARGUMENT_LOGIN' || $exception->getErrorCode() == 'INVALID_ARGUMENT_PASSWORD') { </span></span><span> <span>throw new AuthenticationException('Invalid username or password'); </span></span><span> <span>} </span></span><span> <span>if ($exception->getErrorCode() == 'INVALID_ARGUMENT_APP_ID') { </span></span><span> <span>throw new AuthenticationException('Invalid app ID'); </span></span><span> <span>} </span></span><span> <span>} </span></span><span> <span>return new UserAppToken( </span></span><span> <span>$user, </span></span><span> <span>$user->getToken(), </span></span><span> <span>$providerKey, </span></span><span> <span>$user->getRoles() </span></span><span> <span>); </span></span><span> <span>} </span></span><span> </span><span> <span>/** </span></span><span><span> * <span>{@inheritdoc} </span></span></span><span><span> */ </span></span><span> <span>public function supportsToken(TokenInterface $token, $providerKey) </span></span><span> <span>{ </span></span><span> <span>return $token instanceof UserAppToken </span></span><span> <span>&& $token->getProviderKey() === $providerKey; </span></span><span> <span>} </span></span><span> </span><span> <span>/** </span></span><span><span> * <span>{@inheritdoc} </span></span></span><span><span> */ </span></span><span> <span>public function createToken(Request $request, $username, $password, $providerKey) </span></span><span> <span>{ </span></span><span> <span>return new UserAppToken($username, $password, $providerKey); </span></span><span> <span>} </span></span><span><span>}</span></span>
>这里发生的事情是,我们定义了一个简单的安全区域,该区域使用Authenticator使用Simple_form类型的身份验证。在注销密钥下,我们添加了要调用的处理程序(我们的UserAppLogout类定义为服务)。其余的是常规的Symfony安全设置,因此请确保您确实在登录路线上显示登录表单,等等。请查看有关此信息的文档,以获取更多信息。
>仅此而已。通过使用我们的自定义表单身份验证器和用户提供商(以及可选的注销处理程序),使用Simple_form身份验证,我们已经实现了基于UserApp.io的Symfony Symfony身份验证机制。
结论
在本文中,我们看到了如何使用UserApp.io服务和API作为用户提供商实现自定义符号表单身份验证。我们已经完成了很多代码,这意味着对代码本身的简短说明。相反,我试图通过构建一种自定义解决方案来考虑与UserApp.io交互的方式来解释与Symfony的身份验证过程。>如果您跟随并在捆绑包中实现了此方法并希望这样使用,请继续。您还可以选择使用我创建的库,该库在GitHub页面上具有非常简单的设置。我推荐后者,因为我计划开发和维护它,以便如果删除任何错误或引入了功能(希望不是相反),您始终可以获取更新版本。
如果您想为此做出贡献,您非常欢迎。我也很感谢让我知道您是否发现任何问题或认为有更好的方法可以实现类似的目标。
symfony2和userApp.io
>的经常询问的问题(常见问题解答)>如何将UserApp.io与symfony2集成用于用户身份验证?
>将用户app.io与Symfony2集成用于用户身份验证的symfony2涉及几个步骤。首先,您需要使用Composer安装UserApp库。然后,您需要在Symfony2项目中配置UserApp服务。这涉及设置UserApp API密钥并在Services.yml文件中配置UserApp服务。之后,您可以在控制器中使用UserApp服务对用户进行身份验证。
>>在Symfony2? userApp.io中使用UserApp.io来处理用户角色和权限,提供了一个称为“用户角色”的功能,该功能允许您管理用户角色和权限。您可以定义不同的角色并将其分配给用户。然后,您可以检查用户在Symfony2 Controller中的角色,以控制对应用程序不同部分的访问。 userapp.io in userapp.io处理用户注册。提供了一个称为“用户注册”的功能,该功能允许您在Symfony2应用程序中处理用户注册。您可以在控制器中使用UserApp服务来注册新用户。 UserApp服务将处理注册过程,包括验证用户的电子邮件和密码,以及创建新的用户帐户。 > > userApp.io提供的用户身份验证过程来自定义用户身份验证过程。用户身份验证过程的许多自定义选项。您可以自定义登录表,注册表格,密码重置表格等。您还可以通过将自定义字段添加到用户配置文件中,或通过实现自定义身份验证逻辑来自定义用户身份验证过程。 >如何将现有的用户数据迁移到Symfony2? > userApp.io中与userApp.io进行故障排除,提供了许多故障排除工具,这些工具可以帮助您在Symfony2中与UserApp.io进行故障排除问题。它提供详细的错误消息,记录和调试工具。您还可以使用UserApp API来解决用户应用服务问题的问题。 USERAPP API提供了许多端点,您可以使用这些端点来调试和解决用户应用服务的问题。>我如何使用symfony2?
>如何使用Symfony2?
userApp中的userApp.io处理密码重置.IO提供了一个称为“密码重置”的功能,该功能允许您在Symfony2应用程序中处理密码重置。您可以在控制器中使用UserApp服务来重置用户的密码。 USERAPP服务将处理密码重置过程,包括向用户发送密码重置电子邮件。>如何使用userapp.io?
userApp保护我的Symfony2应用程序。 IO提供了许多安全功能,可以帮助您保护Symfony2应用程序。它提供安全的用户身份验证,安全的密码存储和安全的用户管理。它还提供了诸如两因素身份验证和IP白名单之类的功能,这些功能可以进一步增强您的应用程序的安全性。
>>我如何在Symfony2?
以上是用户symfony2与userApp.io中的用户身份验证的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

JWT是一种基于JSON的开放标准,用于在各方之间安全地传输信息,主要用于身份验证和信息交换。1.JWT由Header、Payload和Signature三部分组成。2.JWT的工作原理包括生成JWT、验证JWT和解析Payload三个步骤。3.在PHP中使用JWT进行身份验证时,可以生成和验证JWT,并在高级用法中包含用户角色和权限信息。4.常见错误包括签名验证失败、令牌过期和Payload过大,调试技巧包括使用调试工具和日志记录。5.性能优化和最佳实践包括使用合适的签名算法、合理设置有效期、

会话劫持可以通过以下步骤实现:1.获取会话ID,2.使用会话ID,3.保持会话活跃。在PHP中防范会话劫持的方法包括:1.使用session_regenerate_id()函数重新生成会话ID,2.通过数据库存储会话数据,3.确保所有会话数据通过HTTPS传输。

SOLID原则在PHP开发中的应用包括:1.单一职责原则(SRP):每个类只负责一个功能。2.开闭原则(OCP):通过扩展而非修改实现变化。3.里氏替换原则(LSP):子类可替换基类而不影响程序正确性。4.接口隔离原则(ISP):使用细粒度接口避免依赖不使用的方法。5.依赖倒置原则(DIP):高低层次模块都依赖于抽象,通过依赖注入实现。

在PHPStorm中如何进行CLI模式的调试?在使用PHPStorm进行开发时,有时我们需要在命令行界面(CLI)模式下调试PHP�...

PHP8.1中的枚举功能通过定义命名常量增强了代码的清晰度和类型安全性。1)枚举可以是整数、字符串或对象,提高了代码可读性和类型安全性。2)枚举基于类,支持面向对象特性,如遍历和反射。3)枚举可用于比较和赋值,确保类型安全。4)枚举支持添加方法,实现复杂逻辑。5)严格类型检查和错误处理可避免常见错误。6)枚举减少魔法值,提升可维护性,但需注意性能优化。

如何在系统重启后自动设置unixsocket的权限每次系统重启后,我们都需要执行以下命令来修改unixsocket的权限:sudo...

静态绑定(static::)在PHP中实现晚期静态绑定(LSB),允许在静态上下文中引用调用类而非定义类。1)解析过程在运行时进行,2)在继承关系中向上查找调用类,3)可能带来性能开销。
