> 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></span>然後調用supportToken()方法來檢查此類是否支持createToken()返回的令牌。在這裡,我們只是確保我們為令牌類型返回。
>
>最後,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></span>>類似於表單Authenticator類,我們使用依賴項注入將UserApp.io客戶端注入此類,並實現了UserProviderInterface。後者需要我們有3種方法:
- > 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></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></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></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></span>>其他三個是我們之前寫過的表單身份驗證者,用戶提供商和註銷類。如您所記得的那樣,每個人都以定義為第一個服務的UserApp.io客戶端的形式接受其構造函數中的一個參數。
接下來,是時候在我們的安全系統中使用這些服務了,因此編輯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></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中文網其他相關文章!

Laravel使用其直觀的閃存方法簡化了處理臨時會話數據。這非常適合在您的應用程序中顯示簡短的消息,警報或通知。 默認情況下,數據僅針對後續請求: $請求 -

PHP客戶端URL(curl)擴展是開發人員的強大工具,可以與遠程服務器和REST API無縫交互。通過利用Libcurl(備受尊敬的多協議文件傳輸庫),PHP curl促進了有效的執行

Laravel 提供简洁的 HTTP 响应模拟语法,简化了 HTTP 交互测试。这种方法显著减少了代码冗余,同时使您的测试模拟更直观。 基本实现提供了多种响应类型快捷方式: use Illuminate\Support\Facades\Http; Http::fake([ 'google.com' => 'Hello World', 'github.com' => ['foo' => 'bar'], 'forge.laravel.com' =>

PHP日誌記錄對於監視和調試Web應用程序以及捕獲關鍵事件,錯誤和運行時行為至關重要。它為系統性能提供了寶貴的見解,有助於識別問題並支持更快的故障排除

您是否想為客戶最緊迫的問題提供實時的即時解決方案? 實時聊天使您可以與客戶進行實時對話,並立即解決他們的問題。它允許您為您的自定義提供更快的服務

文章討論了PHP 5.3中介紹的PHP中的晚期靜態結合(LSB),允許靜態方法的運行時間分辨率調用以更靈活的繼承。 LSB的實用應用和潛在的觸摸


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。