ホームページ >バックエンド開発 >PHPチュートリアル >symfony2のユーザー認証は、userapp.ioを使用しています

symfony2のユーザー認証は、userapp.ioを使用しています

Christopher Nolan
Christopher Nolanオリジナル
2025-02-18 09:47:08471ブラウズ

symfony2のユーザー認証は、userapp.ioを使用しています

userapp.ioは、便利なユーザー管理ツールとAPIです。ユーザーアカウント(およびこれに含まれる多くの機能)を扱うWebインターフェイスと、それらを独自のWebアプリケーションにフックするAPIを提供します。このサービスの目的は、自分のサーバーでそれを心配する必要がないことにより、ユーザー認証をより簡単かつ安全に管理することです。

symfony2のユーザー認証は、userapp.ioを使用しています

多くのプログラミング言語とフレームワーク用のSDKとさまざまなラッパーがあり、価格は手頃な価格です。はい、価格が付属していますが、プレイすることが非常にたくさんあることで自由に始めることができます。詳細情報を入手するには、機能ページをチェックすることをお勧めします。また、アカウントを作成してユーザーの作成、プロファイルへのプロパティの追加などを実験するのは非常に簡単です。そのため、まだお勧めしない場合は、確認することをお勧めします。

この記事では、symfony2認証メカニズムをuserapp.ioを活用する方法を実装する方法を検討します。私たちが書くコードは、私が作成したこの小さなライブラリ(現在開発中)で、試してみることができるコードも見つけることができます。 Symfonyアプリにインストールするには、GitHubの指示に従ってください。

キーテイクアウト

    userApp.ioは、包括的なユーザー管理APIを提供し、サーバー側の懸念なしにユーザー認証を処理するために簡単で安全にします。
  • symfony2 userapp.ioとの統合は、PHPライブラリを介して促進されます。PHPライブラリは、作曲家を介して簡単にインストールでき、Symfonyのサービスフレームワーク内で構成可能です。 フォーム認証器、ユーザープロバイダー、ログアウトハンドラーなどのカスタムクラスは、Symfony2内のuserApp.ioを活用して、シームレスな認証プロセスを有効にするために不可欠です。 Symfony2のフォームAuthenticatorクラスは、ユーザーログインの試みを処理し、userapp.ioの応答に基づいてトークンを作成および認証します。 Symfony2のユーザープロバイダーはuserapp.ioと対話してユーザーの詳細を取得し、Symfony互換のユーザーオブジェクトに変換し、役割と権限を効果的に処理します。
  • ログアウトユーザーには、ユーザーがサービスからログアウトされ、プラットフォーム全体の一貫性を維持するために、ユーザーApp.ioと対話するカスタムログアウトハンドラークラスが含まれます。
  • 依存症
  • userApp.ioサービスと通信するために、PHPライブラリを利用します。 symfonyアプリケーションのcomposer.jsonファイルで、githubページで指示されているように、これを必ず必要としてください。
  • 認証クラス
  • symfonyアプリでuserapp.ioユーザーを認証するには、いくつかのクラスを作成します。
    • userapp.io api
    • で認証を実行するために使用されるフォーム認証クラス APIから収集された情報でユーザーを代表するために使用されるカスタムユーザークラス
  • ユーザーを取得し、ユーザークラスのオブジェクトに変換するために使用されるユーザープロバイダークラス
  • symfony認証トークンを表すために使用されるトークンクラス
  • userapp.ioサービスからログアウトすることに役立つログアウトハンドラークラス。
  • ユーザーapp.ioユーザーがアクセス許可セットを持たない場合にスローできる単純な例外クラス(Symfonyの役割に変換すること)

これらのクラスを作成したら、それらの一部をサービスとして宣言し、Symfonyセキュリティシステム内で使用します。

フォーム認証器

最初に、最も重要なクラスであるフォーム認証機を作成します(AppBundleという名前のベストプラクティスのセキュリティ/フォルダー内)。これがコードです、その後説明します:

<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>
ご覧のとおり、SimpleFormAuthenticatorInterfaceを実装しているため、3つのメソッドとコンストラクターがあります。後者は、インスタンス化されたuserapp.ioクライアントとして依存関係を獲得します(サービスコンテナを使用して渡されますが、これについては1分以内です)。

このクラスは、ユーザーがアプリケーションでログインして認証しようとするときにSymfonyによって使用されます。最初に起こることは、createToken()が呼び出されることです。この方法では、送信されたユーザー名とパスワードを組み合わせた認証トークンを返す必要があります。私たちの場合、それは私たちがすぐに定義するUserApptokenクラスのインスタンスになります。

次に、supporttoken()メソッドが呼び出され、このクラスがcreateToken()によって返されたトークンをサポートしているかどうかを確認します。ここでは、トークンタイプに当てはまることを確認してください。

最後に、AuthenticateToken()が呼び出され、トークンの資格情報が有効かどうかを確認しようとします。ここでは、userApp.io PHPライブラリを使用して、これが失敗した場合はログインまたはSymfony認証例外をスローしようとします。ただし、認証が成功した場合、責任あるユーザープロバイダーは、後者に基づいて別のトークンオブジェクトを作成および返却する前に、ユーザーオブジェクトを構築するために使用されます。

Simple UserApptokenクラスをすばやく作成した直後にユーザープロバイダーを作成します。

トークンクラス

ご覧のとおり、これは、より正確になるためのusernamepasswordtokenクラスの単なる拡張機能です(パスワードの代わりにトークンを保存しているため)。

ユーザープロバイダー

次に、認証者がユーザープロバイダーとどのように動作するかを見てみましょう。後者も作成する時です。
<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>
フォームAuthenticatorクラスと同様に、依存関係インジェクションを使用してUserApp.ioクライアントをこのクラスに挿入し、userProviderInterfaceを実装します。後者には、3つの方法が必要です:

  • loaduserbyusername() - 必要ないので今のところ空にしたままにしてください
  • reshuser() - それぞれの認証されたリクエストで呼び出されます
  • supportssclass() - このユーザープロバイダーが(まだ作成されていない)ユーザークラスで動作するかどうかを判断します。
  • 例外クラスは、デフォルトのPHP例外からの単純な拡張機能です:

    Authenticatorに再び戻って、userApp.ioを使用した認証が成功した場合、ユーザーに関するすべての必要な情報を含むユーザープロバイダーによってUserAppuserクラスのオブジェクトが構築されていることがわかります。このオブジェクトを使用すると、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())

    を使用してトークンを作成します
      このトークンの資格情報を認証し、
    1. 認証が成功した場合、ユーザーオブジェクトとその他の情報を含む新しいトークンを作成します
    2. このトークンを返します。これは、Symfonyがセッションにユーザーを保存するために使用するものです。
    3. ユーザープロバイダーのrefreshuser()メソッドも非常に重要です。この方法は、認証されている各ページの更新で現在ログインしているユーザーの新しいインスタンスを取得する責任があります。したがって、認証されたユーザーがファイアウォール内のページのいずれかに移動するたびに、このメソッドはトリガーされます。ポイントは、その間に発生した可能性のあるストレージの変更でユーザーオブジェクトに水分補給することです。
    4. 明らかに、API呼び出しを最小限に抑える必要がありますが、これはハートビートリクエストを送信してuserApp.ioの認証時間を増やす良い機会です。デフォルトでは(ただし、構成可能)、認証された各ユーザートークンは60分間有効ですが、ハートビートリクエストを送信することにより、これは20分延長されます。

    これは、他の2つの機能を実行するのに最適な場所です。

    1. userapp.ioでトークンがその間に期限切れになった場合、symfony認証エクセプトをスローすることにより、symfonyでユーザーをログアウトすることにより、無効な重要な例外が得られます。
    2. ハートビートリクエストは可能な限り安価になっていますが(実際のユーザーデータが取得されないことを意味します)、ユーザーロックされたステータスは例外の形で送信されます。そのため、この機会を利用して、ユーザーオブジェクトもロックされていることをマークできます。ロックされたステータスは、たとえば、アプリケーションでロックされている場合にさまざまなパーツへのアクセスを拒否して、アプリケーションで使用できます。
    3. 必要に応じて、APIリクエストを作成してユーザーオブジェクトをuserApp.ioのデータで更新することもできますが、ほとんどのユースケースではあまり意味がありません。ユーザーが次回にログアウトして戻ると、データを更新できます。しかし、ニーズに応じて、これはここで簡単に実行できます。ただし、userapp.ioへの多くのAPI呼び出しのパフォーマンスへの影響とコストに留意してください。
    そして、基本的にそれは認証ロジックの核心です。

    ユーザークラス

    以前に話していたuserappuserクラスも作成しましょう:

    ここでは特に、userapp.ioからいくつかのデータをマッピングし、インターフェイスで必要なメソッドのいくつかを実装するだけです。さらに、ロック/ロック解除されていないフラッグガーを追加しました

    logout
    <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からログアウトすることです。 すべてを配線して

    クラスができたので、サービスをサービスとして宣言し、認証システムで使用する時が来ました。 YMLベースのサービス宣言は次のとおりです
    <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>

    最初のものは、パラメーターへの参照の形式でアプリケーションIDを渡すuserapp.io phpライブラリです。 userapp.ioアプリIDを使用して、userapp_idというパラメーターが必要です。

    他の3つは、以前に書いたフォームAuthenticator、ユーザープロバイダー、ログアウトクラスです。そして覚えているように、それぞれが最初のサービスとして定義されたuserapp.ioクライアントの形でコンストラクターの1つのパラメーターを受け入れます。

    次に、これらのサービスをセキュリティシステムで使用する時が来たので、セキュリティを編集して以下を実行します。

    <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><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>

    ここで起こるのは、認証を使用してSimple_Formタイプの認証を使用するシンプルな安全な領域を定義することです。ログアウトキーの下で、呼び出されるハンドラーを追加します(サービスとして定義されているユーザーアプローチクラス)。残りは定期的なSymfonyセキュリティのセットアップですので、ログインルートなどにログインフォームが表示されていることを確認してください。詳細については、これに関するドキュメントをご覧ください。

    そしてそれだけです。 Custom Form Authenticatorおよびユーザープロバイダー(オプションのログアウトハンドラーとともに)でSimple_Form認証を使用することにより、独自のUserApp.ioベースのSymfony認証メカニズムを実装しました。

    結論

    この記事では、ユーザープロバイダーとしてuserapp.ioサービスとAPIを使用してカスタムSymfonyフォーム認証を実装する方法を見てきました。私たちはかなりの多くのコードを経験しました。これは、コード自体の非常に簡単な説明を意味します。むしろ、userapp.ioと対話できる方法を考慮したカスタムソリューションを構築することにより、Symfonyで認証プロセスをSymfonyで説明しようとしました。

    フォローしてバンドル内にこのメソッドを実装し、このように使用したい場合は、先に進みます。また、GitHubページに記述されている非常に迅速で簡単なセットアップがあるライブラリを使用するオプションもあります。後者をお勧めします。なぜなら、バグが削除されたり導入されたりした場合にいつでも更新されたバージョンを入手できるように、開発と維持を計画しているためです(逆ではないことを期待してください)。

    あなたがそれに貢献したいなら、どういたしまして。また、問題を見つけたり、同様の目標を達成するためのより良い方法があると思ったりすることも感謝しています。 Symfony2およびuserApp.io

    を使用したユーザー認証に関するよくある質問(FAQ)

    ユーザー認証のためにuserapp.ioをsymfony2と統合するにはどうすればよいですか?

    ユーザー認証のためにsymfony2とsymfony2を統合するには、いくつかのステップが含まれます。まず、Composerを使用してUserAppライブラリをインストールする必要があります。次に、symfony2プロジェクトでuserappサービスを構成する必要があります。これには、userapp APIキーのセットアップと、services.ymlファイルでuserappサービスを構成することが含まれます。その後、ユーザーを認証するためにコントローラーのuserAppサービスを使用できます。 Symfony2のユーザー認証の利点。ユーザー認証、登録、パスワードリセットなどの既製のソリューションを提供することにより、ユーザー管理のプロセスを簡素化します。また、ユーザー認証のための安全でスケーラブルなソリューションを提供します。これは、大規模なアプリケーションにとって非常に有益です。userapp.ioは、symfony2のuserapp.ioの問題をトラブルシューティングするのに役立つ多くのトラブルシューティングツールを提供します。詳細なエラーメッセージ、ロギング、およびデバッグツールを提供します。 UserApp APIを使用して、UserAppサービスの問題をトラブルシューティングすることもできます。 userapp APIには、ユーザーAppersサービスの問題をデバッグおよびトラブルシューティングに使用できる多くのエンドポイントを提供します。

以上がsymfony2のユーザー認証は、userapp.ioを使用していますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。