Zend Frameworkワークショップ。 パート1:認証とACL







最近、Webアプリケーションを作成するためのプラットフォームとしてのZend Frameworkの汎用性をますます確信しています。 今日は、Zend Frameworkでサイトフレームワークを作成するプロセスについて説明します。このプロセスは、中程度の複雑さのサイトの実装に必要な基盤を提供します

認証



認証は、ほとんどすべてのサイトに不可欠な部分です。 ご存知のように、Zend Frameworkはこれらの目的のために特別なZend_Authコンポーネントを使用します。 このコンポーネントを使用すると、ログインとパスワードのペアが一致するかどうかを確認してシステムに入ることができます。 通常、エントリポイントは特別な認証アクションであり、アクションの登録(または登録確認)です。 簡単な認証の例を考えてみましょう。

public function authAction(){ $form = new Application_Form_Enter(); if ($form->isValid($this->getRequest()->getPost())){ $bootstrap = $this->getInvokeArg('bootstrap'); $auth = Zend_Auth::getInstance(); $adapter = $bootstrap->getPluginResource('db')->getDbAdapter(); $authAdapter = new Zend_Auth_Adapter_DbTable( $adapter, 'user', 'login', 'password', 'MD5(?)' ); $authAdapter->setIdentity($form->login->getValue()); $authAdapter->setCredential($form->password->getValue()); $result = $auth->authenticate($authAdapter); //       storage    if ($result->isValid()){ $storage = $auth->getStorage(); $storage_data = $authAdapter->getResultRowObject( null, array('activate', 'password', 'enabled')); $user_model = new Application_Model_DbTable_User(); $language_model = new Application_Model_DbTable_Language(); $storage_data->status = 'user'; $storage->write($storage_data); } } }
      
      





これは、使用できる一般的な認証コードです。 完全な作業を行うには、このアクションにユーザー名とパスワードを送信する適切なフォームが必要です。

認証に成功すると、ユーザーデータはZend_Authストレージに保存されます。 さらに、現在のユーザーに関する情報を見つける必要がある場合は、次のようにZend_Auth(Singleton実装であるため、どこでも利用可能)に切り替えることができます。

 $auth = Zend_Auth::getInstance(); //    if ($auth->hasIdentity()){ //     $user_data = $auth->getStorage()->read(); }
      
      





実行する必要があるもう1つの重要な手順は、ユーザーが最初にサイトにアクセスしたときのZend_Authの初期初期化です。 これを行うには、次のメソッドをブートストラップに追加します。

 public function _initAuth(){ $auth = Zend_Auth::getInstance(); $data = $auth->getStorage()->read(); if (!isset($data->status)){ $storage_data = new stdClass(); $storage_data->status = 'guest'; $auth->getStorage()->write($storage_data); } }
      
      





Acl



ほとんどのWebアプリケーションにはいくつかのアクセスステータスがあり、それぞれに特定の特権があります。 ほとんどのサイトでは、特権とその配布は比較的一定であるため、プログラムコードに直接記述されたルールの形式でAclを実装しています。 ステータスと権限の構造が頻繁に変化するシステム(CMSなど)を開発している場合、Aclのより柔軟な実装を構築する必要があります。この権限は、たとえばデータベースに保存されます。

アクセス制御システムが実行する必要のある主なタスクは、特権の設定と実際のアクセス制御です。 これらのタスクを実装するには、2つのコンポーネントが必要です。

リソースがサイトの一部である最も単純なケース、つまり MVC、アクションの観点から。 各ユーザーは、特定の抽象的なステータス(ゲスト、ユーザー、管理者)から権利を継承します。各ステータスの特権については、Aclで説明しています。 Aclを実装するには、Zend_Aclを拡張します。

 class Acl extends Zend_Acl { public function __construct() { //  $this->addRole('guest'); $this->addRole('user', 'guest'); $this->addRole('admin', 'user'); //  //   ! $this->add(new Zend_Acl_Resource('guest_allow')); $this->add(new Zend_Acl_Resource('index/index'),'guest_allow'); //... //   ! $this->add(new Zend_Acl_Resource('user_allow')); $this->add(new Zend_Acl_Resource('user/index'), 'user_allow'); // ... //   ! $this->add(new Zend_Acl_Resource('admin_allow')); $this->add(new Zend_Acl_Resource('admin/index'), 'admin_allow'); //... // , -   $this->deny(null, null, null); $this->allow('guest', 'guest_allow', 'show'); $this->allow('user', 'user_allow', 'show'); $this->allow('admin','admin_allow', 'show'); } public function can($privilege='show'){ //  $request = Zend_Controller_Front::getInstance()->getRequest(); $resource = $request->getControllerName() . '/' . $request->getActionName(); //      if (!$this->has($resource)) return true; //  $storage_data = Zend_Auth::getInstance()->getStorage()->read(); $role = array_key_exists('status', $storage_data)?$storage_data->status : 'guest'; return $this->isAllowed($role, $resource, $privilege); } }
      
      





このコードをapplication / classes / Acl.phpファイルに配置します。

ZFの標準形式で権利のリストを説明します。 ここには、現在のアクションについて現在のユーザーのアクセス権をチェックするメソッドも作成されます。 リソース識別子として、コントローラー/アクション形式が使用されます。 コントローラー内のアクションの権利が変わらないようにシステムを設計する場合、リソース識別子の代わりにコントローラー名のみを使用できます( can



メソッドを変更するcan



忘れないでください)。

柔軟性を高めるために、「特権」の概念を追加します。これにより、アクション内の特定のアクションを制御できます。 表示する特権は「表示」と呼ばれます。

アクセス権のリストがあり、ユーザーが現在のアクションにアクセスできるかどうかを判断できるようになったので、Zend Frameworkリク​​エスト処理サイクルでチェックを実装する必要があります。 これにはフロントコントローラープラグインを作成するのが最適です。 プラグインを使用すると、ディスパッチプロセスのさまざまな段階で指定されたアクションを実行できます。

 class CheckAccess extends Zend_Controller_Plugin_Abstract { /** *  preDispatch      *  controller/action      * generateAccessError * * @param Zend_Controller_Request_Abstract $request */ public function preDispatch(Zend_Controller_Request_Abstract $request) { $acl = Zend_Controller_Front::getInstance()->getParam('bootstrap')->getResource('Acl'); if (!$acl->can()){ $this->generateAccessError(); } } /** *       . *     error     *      . * * @param string $msg */ public function generateAccessError($msg=' !'){ $request = $this->getRequest(); $request->setControllerName ('error'); $request->setActionName('error'); $request->setParam('message', $msg); } }
      
      





このコードをapplication / plugins / CheckAccess.phpファイルに配置します。

このプラグインは、サイトで受信したすべてのリクエストでユーザーアクセスチェックを実行します。 アクセスを確認するには、上記のAclクラスを使用します。 エラーの場合、リクエストはエラー/エラーに焦点を合わせます。 エラーメッセージを正しく表示するには、適切なコードをErrorController.phpに追加する必要があります。

次に、プラグインを接続し、ブートストラップでAclリソースを作成する必要があります。

 public function _initAcl(){ Zend_Loader::loadClass('Acl'); Zend_Loader::loadClass('CheckAccess'); Zend_Controller_Front::getInstance()->registerPlugin(new CheckAccess()); return new Acl(); }
      
      





Zend_Loaderがファイルを探す場所を「知る」ために、application.iniに追加します。

includePaths.plugins = APPLICATION_PATH "/ plugins"

includePaths.classes = APPLICATION_PATH "/クラス"



この投稿のPSは、アクセス制御を実装する方法の1つのみが考慮されています。これは普遍的ではありませんが、ほとんどの小規模サイトのニーズを満たします



All Articles