Ethnaでアクセス制限をする場合、一般的にActionクラスのauthenticate()メソッドを使います。
アクション数が多くなってくると、個別に書くのは面倒なので、継承を駆使する場合が多いと思います。
しかしそれでも、ユーザ権限が何種類もあると、管理が煩雑になってしまいます。
今回は、ユーザ権限ごとのアクセス許可を一元管理する方法を紹介します。
手順
まず、ユーザ種別はdefineしてあるものとします。
define(‘USER_TYPE_ANONYMOUS’, 0);
define(‘USER_TYPE_GUEST’, 1);
define(‘USER_TYPE_MEMBER’, 2);
define(‘USER_TYPE_ADMIN’, 3);
次に、ユーザ種別ごとのアクセス許可を、適当なファイルにグローバル変数で記述します。
グローバル変数にするメリットは、index.phpからControllerを生成する前に読み込めるため、BASIC認証と連動しやすい点です。
このアクセス許可一覧変数では、ユーザ種別定数をキーに、アクセス許可するアクション名一覧の配列を値にします。
require_once ‘Appid_Const.php’; //USER_TYPE_*をdefineしてあるファイルをrequire
/**
* 権限毎のアクセス可能アクション一覧
* アクション名の最後の1文字のみ、ワイルドカードとして*(アスタリスク)を使える
*/
$accept_action_list = array(
USER_TYPE_ADMIN =< array(
‘*’,
),
USER_TYPE_MEMBER =< array(
‘entry_*’,
‘comment_*’,
‘inquiry_*’,
),
USER_TYPE_GUEST =< array(
‘comment_*’,
‘inquiry_*’,
),
USER_TYPE_ANONYMOUS =< array(
‘index’,
‘help’,
),
);
また、Appid_Sessionには、getUserType()
というメソッドを作り、ユーザ種別を取得できるようにしておきます。
そして、以下のメソッドを、Appid_ActionClassに入れます。
/**
* このアクションにアクセスできるかどうか調べる
* @return アクセスできるときtrue, 出来ないときfalse
*/
function _authenticate()
{
global $accept_action_list;
$controller =& $this->backend->getController();
if ($controller->_isAcceptableActionName($controller->getCurrentActionName(), $accept_action_list[USER_TYPE_ANONYMOUS])) {
//ログインなしでアクセスできるアクションの場合
return true;
} else if ($this->session->isStart()) {
$userType = $this->session->getUserType(); //現在の権限を取得
if (is_null($userType)) {
$this->ae->add(null, ‘ログインしていません’);
return false;
}
$list = $accept_action_list[$userType]; //現在の権限でアクセスできるアクション
if (!$controller->_isAcceptableActionName($controller->getCurrentActionName(), $list)) {
$this->ae->add(null, ‘権限がありません’);
return false;
} else {
return true; //認証された
}
} else {
$this->ae->add(null, ‘ログインしていません’);
return false;
}
}
あとは、authenticate()メソッドで
function authenticate()
{
if ($this->_authenticate() === true)
{
return null;
}
return ‘index’; //ログイン画面へ飛ばす
}
とすれば完了です。
全アクションの許可・拒否を一括管理できるので、漏れが無くて安心です。