Zend_Authによる認証 (ログインページを作る)

Zend Frameworkで会員認証(ログインページ)を行うには、Zend_Authを使用すると簡単にできます。

Zend_Authでは、ログインできるかできないか、ログインしているかしてないか、の判断しかしません。
ログインしている人の権限レベルを使用する場合は、Zend_Aclがあります。

重複するID・パスワードに注意
Zend_Dbでの具体的な使用例

Zend_Authでは、ID・パスワードの持ち方に下記のものがあります。

アダプタ名アダプタクラス認証方式
DbTableZend_Auth_Adapter_DbTableデータベーステーブル
HttpZend_Auth_Adapter_Httpベーシック認証やプロキシ認証など
DigestZend_Auth_Adapter_Digestダイジェスト認証(ベーシック認証をよりセキュアにしたもの)
LdapZend_Auth_Adapter_LdapLDAP
OpenIdZend_Auth_Adapter_OpenIdOpenID
InfoCardZend_Auth_Adapter_InfoCard情報カード (Information Cards)

使用方法

ログインできるかどうか

// ここは使用するアダプタによって変わります。
$adapter = 【アダプタにID・パスワードを渡す】

$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($adapter);
if ($result->isValid())
{
    // 認証成功(ログインできる。)
}
else
{
    // 認証失敗(ログインできない。)
}

認証に失敗した場合の詳しい情報はgetCode()メソッドでわかります。

結果コードには次のものがあります。
Zend_Auth_Result::SUCCESS
Zend_Auth_Result::FAILURE
Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND
Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS
Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID
Zend_Auth_Result::FAILURE_UNCATEGORIZED

// ここは使用するアダプタによって変わります。
$adapter = 【アダプタにID・パスワードを渡す】

$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($adapter);
switch ($result->getCode()) {
    case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
        // 【IDが存在しない】
        break;
    case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
        // 【認証に失敗】
        break;
    case Zend_Auth_Result::SUCCESS:
        // 【認証に成功】
        break;
    default:
        // 【その他の理由で認証に失敗】
        break;
}

ログインしているかどうか

$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity())
{
    // ログインしている
}
else
{
    // ログインしていない
}

ログインしているIDを取得する

ログイン時に入力したIDを取得することができます。

$auth = Zend_Auth::getInstance();

$loginid = $auth->getIdentity();

ログアウトする

$auth = Zend_Auth::getInstance();

$auth->clearIdentity();

認証の詳細

認証状態の保持

認証後はセッションの$_SESSION['Zend_Auth']として情報を保持します。

アダプタに共通する保持される情報は、ログイン時に入力したIDのみです。

Array
(
    [Zend_Auth] => Array
        (
            [storage] => 【ログイン時に入力したID】
        )
)

セッションクッキー

セッションを扱うのは、Zend_Authの役割ではありませんが、標準ではZend_Authはセッションを使用します。

認証を行った時点からセッションは始まります。
$auth->authenticate($adapter);
インスタンスを生成したときからではありません。

またログイン時にセッションIDの振り直しは行われませんし、ログアウト時にセッションの破棄も行われません。
このため一度ログインしてしまうと、その後にログアウト・ログインを繰り返してもセッションIDは変わりません。
ログイン中のみセッションを使用するとか、 認証以外にセッションを使わないということであればちゃんと対処したほうがいいです。

[参考記事] セッション固定攻撃

GETクエリのセッションIDを無視するにはphp.iniを次のようにします。

session.use_only_cookies On

よりセキュアなログイン

// ここは使用するアダプタによって変わります。
$adapter = 【アダプタにID・パスワードを渡す】

$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($adapter);
if ($result->isValid())
{
    if(phpversion()>='5.1.0')
    {
        session_regenerate_id(true);
    }
    else
    {
        $old_id = session_id();
        session_regenerate_id();
        @unlink(session_save_path() . 'sess_' . $old_id);
    }
    // 認証成功(ログインできる。)
}
else
{
    // 認証失敗(ログインできない。)
}

よりセキュアなログアウト

$auth = Zend_Auth::getInstance();

$auth->clearIdentity();
@session_destroy();
$cookie_params = session_get_cookie_params();
setcookie(session_name(), '', time()-42000, $cookie_params['path']);

Zend_Dbでの具体的な使用例

$dbAdapterName = 'PDO_MySQL';
$params = array(
  'host' => 【DBサーバのIPなど】
  'username' => 【DBユーザー名】
  'password' => 【DBパスワード】
  'dbname' => 【データベース名】
);

$dbAdapter = Zend_Db::factory($dbAdapterName, $params);
$authAdapter =  new Zend_Auth_Adapter_DbTable($dbAdapter);
$authAdapter->setTableName(【データベーステーブル名】)
    ->setIdentityColumn(【認証アカウントのカラム名】)
    ->setCredentialColumn(【認証パスワードのカラム名】);

$authAdapter->setIdentity($account);
$authAdapter->setCredential($password);
$result = $this->_auth->authenticate($authAdapter);
if ($result->isValid())
{
    // 認証成功(ログインできる。)
}
else
{
    // 認証失敗(ログインできない。)
}

パスワードをMD5などでハッシュ化している場合

$dbAdapterName = 'PDO_MySQL';
$params = array(
  'host' => 【DBサーバのIPなど】
  'username' => 【DBユーザー名】
  'password' => 【DBパスワード】
  'dbname' => 【データベース名】
);

$dbAdapter = Zend_Db::factory($dbAdapterName, $params);
$authAdapter =  new Zend_Auth_Adapter_DbTable($dbAdapter);
$authAdapter->setTableName(【データベーステーブル名】)
    ->setIdentityColumn(【認証アカウントのカラム名】)
    ->setCredentialColumn(【認証パスワードのカラム名】);
    ->setCredentialTreatment('MD5(?)');

$authAdapter->setIdentity($account);
$authAdapter->setCredential($password);
$result = $this->_auth->authenticate($authAdapter);
if ($result->isValid())
{
    // 認証成功(ログインできる。)
}
else
{
    // 認証失敗(ログインできない。)
}

ユーザー情報を論理削除にしている場合

flg_deleteを削除フラグとしたとき

$dbAdapterName = 'PDO_MySQL';
$params = array(
  'host' => 【DBサーバのIPなど】
  'username' => 【DBユーザー名】
  'password' => 【DBパスワード】
  'dbname' => 【データベース名】
);

$dbAdapter = Zend_Db::factory($dbAdapterName, $params);
$authAdapter =  new Zend_Auth_Adapter_DbTable($dbAdapter);
$authAdapter->setTableName(【データベーステーブル名】)
    ->setIdentityColumn(【認証アカウントのカラム名】)
    ->setCredentialColumn(【認証パスワードのカラム名】);
    ->setCredentialTreatment('? AND flg_delete = 1');

$authAdapter->setIdentity($account);
$authAdapter->setCredential($password);
$result = $this->_auth->authenticate($authAdapter);
if ($result->isValid())
{
    // 認証成功(ログインできる。)
}
else
{
    // 認証失敗(ログインできない。)
}

application.ini に設定を記載する方法

application.ini

db.adapter = PDO_MySQL
db.params.host = "【DBサーバのIPなど】"
db.params.username = "【DBユーザー名】"
db.params.password = "【DBパスワード】"
db.params.dbname = "【データベース名】"

auth.tableName           = 【データベーステーブル名】
auth.identityColumn      = 【認証アカウントのカラム名】
auth.credentialColumn    = 【認証パスワードのカラム名】

認証部分

$config = new Zend_Config_Ini(【application.iniのパス】, APPLICATION_ENV);
$dbAdapter = Zend_Db::factory($config->db->adapter, $params);
$authAdapter =  new Zend_Auth_Adapter_DbTable($dbAdapter);
$authAdapter->setTableName($this->memberTableName)
    ->setIdentityColumn($config->authfront->identityColumn)
    ->setCredentialColumn($config->authfront->credentialColumn);

$authAdapter->setIdentity($account);
$authAdapter->setCredential($password);
$result = $this->_auth->authenticate($authAdapter);
if ($result->isValid())
{
    // 認証成功(ログインできる。)
}
else
{
    // 認証失敗(ログインできない。)
}

スポンサーリンク

関連記事

スポンサーリンク

初期に作成されるデータベーステーブル

ホームページ製作・web系アプリ系の製作案件募集中です。

上に戻る