複数のサービスをサポートする単一ユーザー認証

Yii EAuth拡張 Yiiフレームワークでプロジェクトの1つを実装するとき、サードパーティサービス(Google、Facebook、Twitterなど)を介してユーザーを登録および承認するタスクがありました。

この問題には2つの解決策があります。更新:現在のバージョンとセットアップ手順はgithub.comで入手できます。 この記事の手順は、EAuthバージョン<= 1.1.3に適しています。

認証サービスを使用する長所:
  1. インストールのシンプルさと速度。
  2. 各プロバイダーを通じて承認の複雑さを学ぶ必要はありません。

ただし、自己認証には他にもいくつかの利点があります。
  1. 認証プロセスの完全な制御:プロバイダー認証ウィンドウに書き込まれる内容、受信するデータなど。
  2. サイトの設計に応じて承認ウィジェットの外観を変更する機能。
  3. OAuthを介して認証する場合、プロバイダーから提供されている場合、APIメソッドを呼び出すことができます。
  4. サードパーティのサービスへの依存度が低くなり、信頼性が高まります。

私は主にyiiの既製の拡張機能がないため、2番目のオプションを選択しました。そのような認証システムが内部からどのように機能するのか疑問に思いました。 最初は、ユーザー管理モジュールの一部でした。 しかし、後にこの機能は別の拡張機能として割り当てられ、どのプロジェクトでも簡単に使用できます。

1.認証システムの要件


拡張機能を設計するとき、私は次の原則に導かれました。
  1. さまざまなタイプのサービスを介した複雑な認可、各サービスでのアダプターの使用を無視する必要性。
  2. アプリケーションにユーザーを登録するために使用できる一意の認証識別子を取得します。
  3. 標準の許可クラスを拡張して、追加のユーザー情報を取得する機能。
  4. 必要なサービスの許可クラスを拡張することにより、ソーシャルネットワークのAPIを操作する機能。
  5. サイトでサポートされるサービスのリストをカスタマイズする機能により、承認ウィジェットの外観を再定義します。 アプリケーションを閉じずに、承認のためにポップアップウィンドウを使用する機能。

2. EAuth拡張


上記のすべての要件を実装した結果、EAuth拡張機能が生まれました。
現時点では、拡張機能には次のものが含まれています。

3.インストール


最初に、 `protected/extensions/eauth`機能をダウンロードして解凍する必要があります

3.1依存関係


拡張機能は、ロイドEOAuthを使用してそれぞれOpenIDとOAuthを操作します。 これらの拡張機能をダウンロードして、 `protected/extensions`ディレクトリに配置する必要があります。

3.2セットアップ


`main.php`の設定では`main.php`を追加する必要があります:
 'import'=>array( 'ext.eoauth.*', 'ext.eoauth.lib.*', 'ext.lightopenid.*', 'ext.eauth.services.*', ), 'components'=>array( 'loid' => array( 'class' => 'ext.lightopenid.loid', ), 'eauth' => array( 'class' => 'ext.eauth.EAuth', 'popup' => true, // Use the popup window instead of redirecting. 'services' => array( // You can change the providers and their classes. 'google' => array( 'class' => 'GoogleOpenIDService', ), 'yandex' => array( 'class' => 'YandexOpenIDService', ), 'twitter' => array( 'class' => 'TwitterOAuthService', 'key' => '...', 'secret' => '...', ), 'facebook' => array( 'class' => 'FacebookOAuthService', 'client_id' => '...', 'client_secret' => '...', ), 'vkontakte' => array( 'class' => 'VKontakteOAuthService', 'client_id' => '...', 'client_secret' => '...', ), 'mailru' => array( 'class' => 'MailruOAuthService', 'client_id' => '...', 'client_secret' => '...', ), ), ), ), 

拡張機能には、 popupservices 2つのパラメーターしかありません。 popupパラメーターは、プロバイダーのサイトにリダイレクトする代わりに、承認のためにポップアップウィンドウを使用する役割を果たします。 servicesパラメーターは、アプリケーションでサポートされているプロバイダーのリストです。 プロバイダーごとに、プロバイダーの基本クラスに基づいて独自のクラスを指定できます。 OAuthプロバイダーのキーを取得するには、適切なプロバイダーにアプリケーションを登録する必要があります。

4.使用する


例として、 `yiic webapp create`によって生成された標準のYiiアプリケーションを取り上げ、GoogleおよびYandexを介して認証オプションを追加します(キーを混乱させないようにOAuthプロバイダーを接続しません)。 完成したデモをご覧ください

4.1 UserIdentity


最初に、拡張機能を使用してログインするServiceUserIdentityクラスを作成します。 クラスコード:
 <?php class ServiceUserIdentity extends UserIdentity { const ERROR_NOT_AUTHENTICATED = 3; /** * @var EAuthServiceBase the authorization service instance. */ protected $service; /** * Constructor. * @param EAuthServiceBase $service the authorization service instance. */ public function __construct($service) { $this->service = $service; } /** * Authenticates a user based on {@link username}. * This method is required by {@link IUserIdentity}. * @return boolean whether authentication succeeds. */ public function authenticate() { if ($this->service->isAuthenticated) { $this->username = $this->service->getAttribute('name'); $this->setState('id', $this->service->id); $this->setState('name', $this->username); $this->setState('service', $this->service->serviceName); $this->errorCode = self::ERROR_NONE; } else { $this->errorCode = self::ERROR_NOT_AUTHENTICATED; } return !$this->errorCode; } } 

標準プロバイダークラスは、 idname 2つの属性を提供します。 さらに、各プロバイダーには独自の識別子があり、これはserviceNameプロパティに含まれています。 ServiceUserIdentityクラスServiceUserIdentityServiceUserIdentityこれらの属性を現在のユーザーのセッション(およびCookie)に格納します。

4.2 SiteContoller編集


2番目のステップは、 `site/login`を変更することです。 アクションの先頭に次のコードを追加します。
 public function actionLogin() { $service = Yii::app()->request->getQuery('service'); if (isset($service)) { $authIdentity = Yii::app()->eauth->getIdentity($service); $authIdentity->redirectUrl = Yii::app()->user->returnUrl; $authIdentity->cancelUrl = $this->createAbsoluteUrl('site/login'); if ($authIdentity->authenticate()) { $identity = new ServiceUserIdentity($authIdentity); //   if ($identity->authenticate()) { Yii::app()->user->login($identity); //     popup  $authIdentity->redirect(); } else { //  popup     cancelUrl $authIdentity->cancel(); } } // -   ,     $this->redirect(array('site/login')); } //   ... } 

最初に、変数$_GET['service']の存在を確認します。 そのような変数が存在する場合、プロバイダークラスのインスタンスを作成し、リダイレクトおよび承認の取り消しのパスを構成します。 次に、 `$authIdentity->authenticate()`メソッドを呼び出します。このメソッドはすべての魔法を実行します。 メソッド`$authIdentity->redirect();`および`$authIdentity->cancel();` 、使用する場合、ポップアップウィンドウを正しく閉じるために必要です。

4.3ビュー`protected/views/site/login.php`


標準ウィジェットを使用するには、メインフォームの後に数行追加するだけです。
 <h2>Do you already have an account on one of these sites? Click the logo to log in with it here:</h2> <?php Yii::app()->eauth->renderWidget(); ?> 

ウィジェットの外観を変更するには、ファイル`protected/extensions/eauth/views/auth.php` `[theme_name]/views/EAuthWidget/auth.php`ます。

4.4結果


すべての手順が完了したら、Webサイトを開いてログインページに移動できます。 標準認証フォームの後に、認証サービスのアイコンが表示されます:
認証サーバー

たとえば、Googleアイコンをクリックすると、ポップアップウィンドウが開きます。 ポップアップログインンウィンドウ

ユーザーがアプリケーションの承認を確認すると、ユーザーはログインし、 redirectUrlページにredirectUrlます(この例ではYii::app()->user->returnUrl )。 ユーザーが[ No, thanksクリックすると、ポップアップウィンドウが閉じられます。

おわりに


以上で、認証システムは動作する準備が整いました。 拡張機能で他にできること:

参照資料



更新: 「3.2設定」の項目に、ロイド拡張機能の欠如が追加されました。
更新2:現在のバージョンとセットアップ手順はgithub.comで入手できます。 この記事の手順は、EAuthバージョン<= 1.1.3に適しています。

Source: https://habr.com/ru/post/J129804/


All Articles