5

私の目標は、特定のページへのログインを要求することです。Zend Framework MVCを使用しており、ベストプラクティスに関する例を見つけようとしています。

私が探しているものに関するいくつかのメモ:

  • ログインしていないユーザーがログインボックスを取得し、認証されたらログインバージョンのページに戻るようにしたい
  • 依存性注入を使用し、シングルトンを避けたい
  • 小さなコードフットプリント-ZendMVC構造に結び付けます
  • ログインボックスは別のコントローラーであり、ヘッダーリダイレクトを行う必要がありますか?認証が成功した後、ランディングページに戻るにはどうすればよいですか?ログインコントローラーアクションを呼び出して、ランディングページにログインボックスを表示するというアイデアですか、それとも検索エンジンのインデックス作成に関する不利な点ですか?
  • Cookieを処理するために外部ライブラリを使用できる

または完全に異なる何か。私はZendフレームワークにかなり慣れていないので、「正しい方法で」やりたいと思っています。

4

3 に答える 3

4

Zend_AuthZend_Aclの組み合わせを使用できます。他の回答を拡張するために、zendフレームワークを使用して認証を管理する方法の簡単な例を示します。

まず、すべてのリクエストを事前にディスパッチするプラグインを設定し、クライアントが特定のデータへのアクセスを許可されているかどうかを確認する必要があります。このプラグインは次のようになります。

class Plugin_AccessCheck extends Zend_Controller_Plugin_Abstract {

    private $_acl = null;

    public function __construct(Zend_Acl $acl) {
        $this->_acl = $acl;
    }

    public function preDispatch(Zend_Controller_Request_Abstract $request) {
        //get request information
        $module = $request->getModuleName ();
        $resource = $request->getControllerName ();
        $action = $request->getActionName ();

        try {
            if(!$this->_acl->isAllowed(Zend_Registry::get('role'), 
                                $module . ':' . $resource, $action)){
                $request->setControllerName ('authentication')
                        ->setActionName ('login');
            }
        }catch(Zend_Acl_Exception $e) {
            $request->setControllerName('index')->setActionName ('uups');
        }
    }
}

したがって、すべてのユーザータイプには、aclライブラリで定義する特定の権限があります。リクエストごとに、ユーザーがリソースへのアクセスを許可されているかどうかを確認します。ログインページにリダイレクトしない場合、preDispatchはユーザーをリソースに渡します。

Zend_Aclでは、アクセスを許可または拒否する役割、リソース、および権限を定義します。例:

class Model_LibraryAcl extends Zend_Acl {
    public function __construct() {

        $this->addRole(new Zend_Acl_Role('guests'));
        $this->addRole(new Zend_Acl_Role('users'), 'guests');
        $this->addRole(new Zend_Acl_Role('admins'), 'users');                

        $this->add(new Zend_Acl_Resource('default'))
             ->add(new Zend_Acl_Resource('default:authentication'), 'default')
             ->add(new Zend_Acl_Resource('default:index'), 'default')
             ->add(new Zend_Acl_Resource('default:error'), 'default');

        $this->allow('guests', 'default:authentication', array('login'));
        $this->allow('guests', 'default:error', 'error');

        $this->allow('users', 'default:authentication', 'logout');          
    }
}

次に、ブートストラップファイルでaclとauthを設定する必要があります。

    private $_acl = null;

    protected function _initAutoload() {

       //...your code           
       if (Zend_Auth::getInstance()->hasIdentity()){
        Zend_Registry::set ('role',
                     Zend_Auth::getInstance()->getStorage()
                                              ->read()
                                              ->role);
        }else{
            Zend_Registry::set('role', 'guests');
        }

        $this->_acl = new Model_LibraryAcl ();
        $fc = Zend_Controller_Front::getInstance ();
        $fc->registerPlugin ( new Plugin_AccessCheck ( $this->_acl ) );

        return $modelLoader;
    }

最後に、認証コントローラーで、カスタム認証アダプターを使用し、ログインとログアウトのアクションをセットアップする必要があります。

public function logoutAction() {
    Zend_Auth::getInstance ()->clearIdentity ();
    $this->_redirect ( 'index/index' );
}

private function getAuthAdapter() {
    $authAdapter = new Zend_Auth_Adapter_DbTable ( 
                        Zend_Db_Table::getDefaultAdapter ());
    $authAdapter->setTableName('users')
                ->setIdentityColumn('email')
                ->setCredentialColumn ('password')
                ->setCredentialTreatment ('SHA1(CONCAT(?,salt))');

    return $authAdapter;
}

ログインアクションでは、認証を実行する認証アダプタにログインデータを渡す必要があります。

$authAdapter = $this->getAuthAdapter ();
$authAdapter->setIdentity ( $username )->setCredential ( $password );
$auth = Zend_Auth::getInstance ();
$result = $auth->authenticate ( $authAdapter );

if ($result->isValid ()) {
    $identity = $authAdapter->getResultRowObject ();
    if ($identity->approved == 'true') {
        $authStorage = $auth->getStorage ();
        $authStorage->write ( $identity );
        $this->_redirect ( 'index/index' );
    } else {
       $this->_redirect ( 'authentication/login' );
  }

そしてそれがすべてです。zendauthとzendaclのYouTubeでこの方法をお勧めします。

于 2011-04-02T12:15:18.863 に答える
4
  • ログインしていないユーザーがログインボックスを取得し、認証されたらログインバージョンのページに戻るようにしたい

FrontControllerプラグインを使用して、loginActionにリダイレクトまたは転送します。

  • 依存性注入を使用し、シングルトンを避けたい

Zend Frameworkは現在DIシステムを出荷していませんが、Zend_Application_Resource_*が実際にそれを置き換えます。ここではどのような依存関係が必要ですか?

  • 小さなコードフットプリント-ZendMVC構造に結び付けます

それはあなた次第です。

  • ログインボックスは別のコントローラーであり、ヘッダーリダイレクトを行う必要がありますか?認証が成功した後、ランディングページに戻るにはどうすればよいですか?ログインコントローラーアクションを呼び出して、ランディングページにログインボックスを表示するというアイデアですか、それとも検索エンジンのインデックス作成に関する不利な点ですか?

AuthController私は主にLoginAction&で特別なものを使用しLogoutActionます。ユーザーを表示しようとしているページにリダイレクトするために、私は常にreturnUrlフォームに要素を追加し、要求されたURLの値を挿入してユーザーをリダイレクトできるようにします。ない場合は、ユーザーをインデックスにリダイレクトします。ダッシュボード、依存します。

  • Cookieを処理するために外部ライブラリを使用できる

Zend_Authを使用すると、独自のストレージメカニズムを設定できるため、インターフェイスを実装するだけです。

$auth = Zend_Auth::getInstance();
$auth->setStorage(new My_Auth_Storage());

ただし、認証結果をCookieに保存し ないでください。変更や、Webサイトへのアクセスは非常に簡単です。

また、私の以前の回答の1つをご覧になることもできます。

于 2011-04-01T13:25:00.330 に答える
1

これがベストプラクティスかどうかはわかりませんが、その後に実行する場合は、次のようにします。

  1. LoginForm一意に識別可能な送信ボタンを使用してを作成します(後で説明します)
  2. AuthServicewithメソッドgetLoginForm、、、および: login、、、および同様のメソッドのlogout1つまたはすべてを作成します。getIdentityhasIdentity
  3. このサービスのインスタンスを持つビューヘルパーを作成し、その結果に応じて、hasIdentityこの機能を必要とするビューで、LoginFormをレンダリングするか、ログインしたユーザーのIDをレンダリングします。
  4. サービスのインスタンスも持つフロントコントローラープラグインを作成し、preDispatchプラグインフックを実装します。プローブするアクションの構成を指定します。AuthService->hasIdentity()trueが返された場合は、何もしません。リクエストがリクエスト後の場合は、一意に識別可能な送信ボタン名を探します。つまり、使用できない場合は$request->getPost( 'loginSubmitButton', null );デフォルトでにnullなります。そうでない場合はnulllogin( $request->getPost() )サービスで。成功した場合は同じアクションにリダイレクトし、失敗した場合はフォールスルーして、ビューヘルパーでフォームを再度レンダリングします(エラーを自動的に表示します)。

サービスは、ビューヘルパーとフロントコントローラープラグインの両方でフェッチでき、サービスロケーターはブートストラップServiceAbstract::getService( 'Auth' )にサービスを登録するなどの操作を行いServiceAbstractます。

于 2011-04-01T13:26:56.523 に答える