2

私は Zend 2.0 を使用していますが、EXTJS を Zend と組み合わせて使用​​したことはありません。

view/login/index.phtml の extjs コードは次のとおりです。

<?php $this->inlineScript()->captureStart() ?>
var LoginWindow
Ext.onReady(function() {

    LoginWindow = new Ext.create('Ext.window.Window',{
        title: 'Login',
        closable: false,
        draggable: false,
        resizable: false,
        width: 370,
        items: [
            Ext.create('Ext.form.Panel', {
                id: 'LoginForm',

                bodyPadding: 5,
                width: 350, 

                url: '/',
                layout: 'anchor',
                defaults: {
                    anchor: '100%'
                },

                // The fields
                defaultType: 'textfield',
                items: [{
                    fieldLabel: 'Username',
                    name: 'user',
                    allowBlank: false
                },{
                    fieldLabel: 'Password',
                    inputType: 'password',
                    name: 'pw',
                    allowBlank: false
                }],

                // Reset and Submit buttons
                buttons: [{
                    text: 'Reset',
                    handler: function() {
                        this.up('form').getForm().reset();
                    }
                },
                {
                    text: 'Submit',
                    formBind: true,
                    disabled: true,
                    handler: function() {
                        var form = this.up('form').getForm();

                    }
                }]
            })
        ]
    });
    Ext.getBody().mask()

    LoginWindow.show()  

});

<?php $this->inlineScript()->captureEnd() ?>

ユーザー名/パスワードをLoginController.phpに送信し、モデルを使用してデータベーステーブルからユーザー名/パスワードを認証する方法がわかりません。

例や可能な解決策は本当に役に立ちます。

4

4 に答える 4

6

以下をすぐに使用できるソリューションとは見なさないでください。また、ログインの管理を開始するときに役立ついくつかのパーツを追加しました。あなたにとっての主要な部分は、コントローラーのルーティングです。また、ExtJS の部分を除いて、ビューのコンテンツも割愛しました。とにかく、これがお役に立てば幸いです。

まず、フォーム内にいくつかの問題があります。次のものを試してください

var loginWindow;
Ext.onReady(function() {

    loginWindow = new Ext.create('Ext.window.Window',{
        title: 'Login',
        closable: false,
        draggable: false,
        resizable: false,
        width: 370,
        modal: true,
        items: [
            Ext.create('Ext.form.Panel', {
                id: 'LoginForm',
                bodyPadding: 5,
                width: 350, 
                layout: 'anchor',
                defaults: {
                    anchor: '100%'
                },
                defaultType: 'textfield',
                items: [{
                    fieldLabel: 'Username',
                    name: 'user',
                    allowBlank: false
                },{
                    fieldLabel: 'Password',
                    inputType: 'password',
                    name: 'pw',
                    allowBlank: false
                }],

                url: 'Login/Auth', // first one should be your controller, second one the controller action (this one need to accept post)
                buttons: [
                    {
                        text: 'Reset',
                        handler: function() {
                            this.up('form').getForm().reset();
                        }
                    },
                    {
                        text: 'Submit',
                        formBind: true,
                        disabled: true,
                        handler: function() {
                            var form = this.up('form').getForm();
                            if (form.isValid()) {
                                form.submit({
                                    success: function(form, action) {
                                       Ext.Msg.alert('Success', 'Authenticated!');
                                    },
                                    failure: function(form, action) {
                                        Ext.Msg.alert('Failed', 'Authentication Failed');
                                    }
                                });
                            }
                        }
                    }
                ]
            })
        ]
    }).show();
    // Ext.getBody().mask(); <- modal property does the same
});

これからZF2へ

ルーティング

アプリケーションの各ページはアクションと呼ばれ、アクションはモジュール内のコントローラーにグループ化されます。したがって、通常、関連するアクションをコントローラーにグループ化します。

特定のアクションへの URL のマッピングは、モジュールの module.config.php ファイルで定義されているルートを使用して行われます。Login アクションのルートを追加する必要があります。これは、コメント ブロック内に新しいコードを含む、更新されたモジュール構成ファイルです。

<?php
return array(
    'controllers' => array(
        'invokables' => array(
            'Login\Controller\Login' => 'Login\Controller\LoginController',
        ),
    ),

    // The following section is new and should be added to your file
    'router' => array(
        'routes' => array(
            'login' => array(
                'type'    => 'segment',
                'options' => array(
                    'route'    => '/login[/:action][/:username][/:password]',
                    'constraints' => array(
                        'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
                        'username' => '[a-zA-Z][a-zA-Z0-9_-]*',
                        'password' => '[a-zA-Z][a-zA-Z0-9_-]*',
                    ),
                    'defaults' => array(
                        'controller' => 'Login\Controller\Login',
                        'action'     => 'index',
                    ),
                ),
            ),
        ),
    ),

    'view_manager' => array(
        'template_path_stack' => array(
            'login' => __DIR__ . '/../view',
        ),
    ),
);

ルートの名前は「ログイン」で、タイプは「セグメント」です。セグメント ルートを使用すると、一致したルートの名前付きパラメーターにマップされる URL パターン (ルート) でプレースホルダーを指定できます。この場合、ルートは/login[/:action][/:id]で、/login で始まるすべての URL に一致します。次のセグメントはオプションのアクション名になり、最後に次のセグメントはオプションの ID にマップされます。角括弧は、セグメントがオプションであることを示します。制約セクションを使用すると、セグメント内の文字が期待どおりであることを確認できるため、文字で始まり、その後の文字が英数字、アンダースコア、またはハイフンのみになるようにアクションを制限できます。

コントローラー

次に、コントローラーをセットアップする必要があります。コントローラは、一般に{コントローラ名}Controller.と呼ばれるクラスです。{Controller name} は大文字で始める必要があることに注意してください。このクラスは、モジュールの Controller ディレクトリ内の {Controller name}Controller.php というファイルにあります。あなたの場合は、module/Login/src/Login/Controller のようなものになります。各アクションは、{action name}Action という名前のコントローラー クラス内のパブリック メソッドです。あなたの場合、{action name} は小文字で始める必要があります。

<?php
namespace Login\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;

class LoginController extends AbstractActionController
{
    public function authenticateAction($username, $password)
    {
        $params = array('driver' => 'driver',
                        'dbname' => 'name');

        $db = new DbAdapter($params);

        use Zend\Authentication\Adapter\DbTable as AuthAdapter;
        // Oversimplified example without even hashing the password
        $adapter = new AuthAdapter($db,
                                   'Logins',
                                   'username',
                                   'password'
                                   );

        // get select object (by reference)
        $this->_adapter->setIdentity($username);
        $this->_adapter->setCredential($password);

        $result = $adapter->authenticate();

        if($result->isValid()) {
            // authenticated
        }
    }

    protected $loginTable;
    public function getLoginTable()
    {
        if (!$this->loginTable) {
            $sm = $this->getServiceLocator();
            $this->loginTable = $sm->get('Login\Model\LoginTable');
        }
        return $this->loginTable;
    }
}

ビュースクリプト

これらのファイルは DefaultViewStrategy によって実行され、コントローラー アクション メソッドから返される変数またはビュー モデルが渡されます。これらのビュー スクリプトは、コントローラにちなんで名付けられたディレクトリ内のモジュールのビュー ディレクトリに保存されます。次の 4 つの空のファイルを作成します。

module/Login/view/login/login/authenticate.phtml`

モデル

module/Login/src/Login/Modelの下にLogin.phpというファイルを作成します。

<?php
namespace Login\Model;

class Login
{
    public $id;
    public $username;
    public $password;

    public function exchangeArray($data)
    {
        $this->id     = (isset($data['id'])) ? $data['id'] : null;
        $this->username = (isset($data['username'])) ? $data['username'] : null;
        $this->password  = (isset($data['password'])) ? $data['password'] : null;
    }
}

次のように、 module/Login/src/Login/ModelディレクトリにLoginTable.phpファイルを作成します。

<?php
namespace Login\Model;

use Zend\Db\TableGateway\TableGateway;

class LoginTable
{
    protected $tableGateway;

    public function __construct(TableGateway $tableGateway)
    {
        $this->tableGateway = $tableGateway;
    }

    public function fetchAll()
    {
        $resultSet = $this->tableGateway->select();
        return $resultSet;
    }

    public function getLogin($id)
    {
        $id  = (int) $id;
        $rowset = $this->tableGateway->select(array('id' => $id));
        $row = $rowset->current();
        if (!$row) {
            throw new \Exception("Could not find row $id");
        }
        return $row;
    }

    public function saveLogin(Login $login)
    {
        $data = array(
            'username' => $login->password,
            'password'  => $login->username,
        );

        $id = (int)$login->id;
        if ($id == 0) {
            $this->tableGateway->insert($data);
        } else {
            if ($this->getLogin($id)) {
                $this->tableGateway->update($data, array('id' => $id));
            } else {
                throw new \Exception('Form id does not exist');
            }
        }
    }

    public function deleteLogin($id)
    {
        $this->tableGateway->delete(array('id' => $id));
    }
}

ServiceManager を使用してテーブル ゲートウェイを構成し、LoginTable に挿入します。

このメソッドをmodule/LoginのModule.phpファイルの最後に追加します。

<?php
namespace Login;

// Add these import statements:
use Login\Model\Login;
use Login\Model\LoginTable;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;

class Module
{
    // getAutoloaderConfig() and getConfig() methods here

    // Add this method:
    public function getServiceConfig()
    {
        return array(
            'factories' => array(
                'Login\Model\LoginTable' =>  function($sm) {
                    $tableGateway = $sm->get('LoginTableGateway');
                    $table = new LoginTable($tableGateway);
                    return $table;
                },
                'LoginTableGateway' => function ($sm) {
                    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new Login());
                    return new TableGateway('login', $dbAdapter, null, $resultSetPrototype);
                },
            ),
        );
    }
}

最後に、 Zend\Db\Adapter\Adapterを取得する方法を認識できるように ServiceManager を構成する必要があります。次のコードでconfig/autoload/global.phpを変更します

<?php
return array(
    'db' => array(
        'driver'         => 'Pdo',
        'dsn'            => 'mysql:dbname=zf2tutorial;host=localhost',
        'driver_options' => array(
            PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
        ),
    ),
    'service_manager' => array(
        'factories' => array(
            'Zend\Db\Adapter\Adapter'
                    => 'Zend\Db\Adapter\AdapterServiceFactory',
        ),
    ),
);

データベースの資格情報をconfig/autoload/local.phpに配置する必要があります

<?php
return array(
    'db' => array(
        'username' => 'YOUR USERNAME HERE',
        'password' => 'YOUR PASSWORD HERE',
    ),
);

次のコード スニペットも役立つ場合があります (テストデモをご覧ください)。

https://github.com/zendframework/zf2

于 2012-11-15T09:31:47.883 に答える
0

1 つの質問に複数の問題があります。パスワードを検証する方法については Zend_Auth を、リクエストからパラメーターを取得する方法については Zend_Controller を、それらのパラメーターを送信する方法については Zend_Form を、いくつかの js をアプリの残りの部分と関連付ける方法については Zend_View を、それぞれ学習することから始めます。

つまり、パスワードとユーザー名はフォームを介して送信され、アプリケーションは Request オブジェクトから getParams メソッドを介してそれらを取得します。

私はあなたに送るリンクが多すぎません.ZF2のドキュメントは今のところかなりの数です.

于 2012-11-13T13:53:23.360 に答える
0

あなたが求めていることはあまり明確ではないので、一般的な回答を書きます。それは zend フレームワークに固有のものではありません。私は zend フレームワークを知りません。ただし、次の点は、認証に使用するすべてのテクノロジに適用できます。

  1. サーバーに対して通常の形式の POST を実行する必要があります。次のいずれかを使用してAJAX投稿を送信することにより、extjsでそれを実現できます

    form.submit(options)
    

    standardSubmit : trueまたは、フォームに設定して通常の HTML 送信を行います。両方のドキュメントはこちらこちらにあります。のドキュメントで引用されているようにExt.form.Panel

    FormPanel の構成オプションとしてリストされていませんが、FormPanel クラスは Ext.form.Basic クラスでサポートされているすべての構成オプションを受け入れ、作成時に内部の BasicForm にそれらを渡します。

  2. セキュリティ上の理由から、パスワードは暗号化された形式で DB に格納する必要があります。また、同じセキュリティ上の理由から、DB から保存されたパスワードを復号化した後、パスワードをコードで比較しないでください。したがって、認証のための標準的なクエリは次のようになります

    select * from users where username='username' and password='password'
    

    上記のクエリに渡されるパスワードも暗号化する必要があります。上記のクエリの結果は、ユーザーが正常に認証されたかどうかを判断する必要があります。クエリが 0 の結果を返す場合、認証は失敗しています。また、上記のスタイルを使用する利点は、追加のクエリを作成しなくてもセッションに関連付けることができるユーザー オブジェクトがあることです。

したがって、フォローは次のようになります。

  1. 役職
  2. コントローラーがリクエストをキャッチ
  3. ユーザー名のパスワードを取得します
  4. サービスへのパス
  5. サービスはエンクリプタを呼び出し、暗号化されたパスワードを取得します
  6. ユーザー名と暗号化されたパスワードを DAO に渡します
  7. DAO はクエリを実行し、結果を返します サービス
  8. サービスは、ユーザーが認証されたかどうかを判断し、決定をコントローラーに渡します
  9. コントローラーは適切な応答をユーザーに送信します

これがあなたの質問に答えることを願っています。

于 2012-11-15T06:32:39.210 に答える