> 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中文網其他相關文章!

在PHP中,可以使用session_status()或session_id()來檢查會話是否已啟動。 1)使用session_status()函數,如果返回PHP_SESSION_ACTIVE,則會話已啟動。 2)使用session_id()函數,如果返回非空字符串,則會話已啟動。這兩種方法都能有效地檢查會話狀態,選擇使用哪種方法取決於PHP版本和個人偏好。

sessionsarevitalinwebapplications,尤其是在commercePlatform之前。

在PHP中管理並發會話訪問可以通過以下方法:1.使用數據庫存儲會話數據,2.採用Redis或Memcached,3.實施會話鎖定策略。這些方法有助於確保數據一致性和提高並發性能。

PHPsessionshaveseverallimitations:1)Storageconstraintscanleadtoperformanceissues;2)Securityvulnerabilitieslikesessionfixationattacksexist;3)Scalabilityischallengingduetoserver-specificstorage;4)Sessionexpirationmanagementcanbeproblematic;5)Datapersis

負載均衡會影響會話管理,但可以通過會話複製、會話粘性和集中式會話存儲解決。 1.會話複製在服務器間複製會話數據。 2.會話粘性將用戶請求定向到同一服務器。 3.集中式會話存儲使用獨立服務器如Redis存儲會話數據,確保數據共享。

Sessionlockingisatechniqueusedtoensureauser'ssessionremainsexclusivetooneuseratatime.Itiscrucialforpreventingdatacorruptionandsecuritybreachesinmulti-userapplications.Sessionlockingisimplementedusingserver-sidelockingmechanisms,suchasReentrantLockinJ

PHP會話的替代方案包括Cookies、Token-basedAuthentication、Database-basedSessions和Redis/Memcached。 1.Cookies通過在客戶端存儲數據來管理會話,簡單但安全性低。 2.Token-basedAuthentication使用令牌驗證用戶,安全性高但需額外邏輯。 3.Database-basedSessions將數據存儲在數據庫中,擴展性好但可能影響性能。 4.Redis/Memcached使用分佈式緩存提高性能和擴展性,但需額外配

Sessionhijacking是指攻擊者通過獲取用戶的sessionID來冒充用戶。防範方法包括:1)使用HTTPS加密通信;2)驗證sessionID的來源;3)使用安全的sessionID生成算法;4)定期更新sessionID。


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

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

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

禪工作室 13.0.1
強大的PHP整合開發環境

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