kazpgmの日記

『プログラム自動作成@自動生成』作成の日記

TOOL更新_今日はトークンチェッククラス

TOOL更新_今日はトークンチェッククラス。まだ実験中なのでコーディング規約には沿っていないけど、徐々に、このページを直接直していくことにする。

■使い方はこんな感じ
・ControllerAdminBase.phpの_commActSubメソッドで使用

if (TokenHandle::isTokenValid($this->_getAdminKbn(), $this->_o, strtolower($this->_o['mode']), 
                     $this->_getAdminKbn() == AppConst::VAL_USER) == false) { // 管理者側トークンチェック
    // トークンチェックエラー場合
    throw new AppException('画面遷移(トークンチェック)エラーです。');
}

・logininfoRegisterView.html(smartyのtemplates)

{{kaz_token_html namespace='admin'}}

・AppSmartyPlugin.phpsmartyプラグイン

/**
 * -------------------------------------------------------------
 * Smarty {kaz_token_html} function plugin
 *
 * Type:     function<br>
 * Name:     kaz_token_html<br>
 * Input:<br>
 *           - namespace    Zend_Session_Namespace用namespace名
 *           - base         "":post用、""以外:get用
 * Purpose:  TokenHandleからTokenHtmlを取得して戻します。
 * @param array
 * @param Smarty
 * @return string
 * -------------------------------------------------------------
 **/
function smarty_function_kaz_token_html($params, &$smarty)
{
    require_once('TokenHandle.php');

    if( isset($params['namespace']) == false){
        $smarty->trigger_error("kaz_token_html: missing 'namespace' parameter");
        return;
    }
    if( isset($params['base']) == false){
        $params['base'] = ''; 
    }
    if(mb_strwidth($params['namespace']) == 0 ){ // パラメータに値がない場合
        $rtn = "";
    } else {
        $rtn = TokenHandle::getTokenHtml($params['namespace'], $params['base']);
    }
    return $rtn;
}

■TokenHandle.php

<?php
//  =============================================================
//  2010 kaz PHP自動作成お助けTOOL.(http://kazpgm.ddo.jp/) Start
//  修正BSDライセンス。
//  =============================================================
//トークンチェッククラス
class TokenHandle {

    // トークンHidden取得
    function getTokenHtml($namespace = "", $base = "") {
        // トークン作成
        $sessObj = new Zend_Session_Namespace($namespace);    // admin/user用セッション
        $sess = $sessObj->array;    // セッションデータ(array)
        $latest_token =  md5(uniqid(rand(),TRUE));
        if (!is_array($sess['KAZ_TOOL_token'])) { // トークンは配列で保存する
            $sess['KAZ_TOOL_token'] = array();
        } else {
            if (count($sess['KAZ_TOOL_token']) > 9) { // トークンは直近10個保存
                array_shift($sess['KAZ_TOOL_token']);
            }
        }
        if (!is_array($sess['KAZ_TOOL_token_time'])) { // トークン時間は配列で保存する
            $sess['KAZ_TOOL_token_time'] = array();
        } else {
            if (count($sess['KAZ_TOOL_token_time']) > 9) { // トークン時間は直近10個保存
                array_shift($sess['KAZ_TOOL_token_time']);
            }
        }
        $sess['KAZ_TOOL_token'][$latest_token] = $latest_token; // トークン保存
        $sess['KAZ_TOOL_token_time'][$latest_token] = time();   // トークン時間保存
        $sessObj->array = $sess;
        if ($base == "") {
            return '<input type="hidden" name="KAZ_TOOL_token" value="'. $latest_token .'" />' ;
        } else {
            return 'KAZ_TOOL_token='. $latest_token;
        }
    }


    // トークンチェック
    function isTokenValid($namespace = "", &$vars, $mode, $userFlg = true) {
        $sessObj = new Zend_Session_Namespace($namespace);    // admin/user用セッション
        $sess = $sessObj->array;    // セッションデータ(array)
        $modeMach = false; // トークンチェックフラグ初期化
        $mode_ary = explode(',', 'ins_do,upd_do,del_do,up_csv' ); // トークンチェック対象モード配列
        for($i = 0; $i < count($mode_ary); $i++) {
            if (trim($mode_ary[$i]) == $mode) { // 'ins_do,upd_do,del_do,up_csv'の中にあれば
                $modeMach = true;  // トークンチェックする
                break;
            }
        }

        if ($modeMach == true) { // トークンチェックする場合
            if (!empty($sess['KAZ_TOOL_token']) && is_array($sess['KAZ_TOOL_token']) &&
                $vars['KAZ_TOOL_token'] == $sess['KAZ_TOOL_token'][$vars['KAZ_TOOL_token']]) {
                $token_age = time() - $sess['KAZ_TOOL_token_time'][$vars['KAZ_TOOL_token']];
                if (($userFlg == false && 
                     $token_age > (180 * 60)) || // 管理者は3時間OK
                    ($userFlg == true && 
                     $token_age > (60 * 60))) { // ユーザは1時間OK(深い理由はない)
                    // OK:トークン削除
                    unset($sess['KAZ_TOOL_token'][$vars['KAZ_TOOL_token']]);
                    unset($sess['KAZ_TOOL_token_time'][$vars['KAZ_TOOL_token']]);
                    $sessObj->array = $sess;
                }
            } else {
                return false;
            }
            return true;
        }
        // OK
        return true;
    }
}
//  =============================================================
//  2010 kaz PHP自動作成お助けTOOL.(http://kazpgm.ddo.jp/) End
//  修正BSDライセンス。
//  =============================================================

http://kazpgm.ddo.jp/

02/11 16:00-18:00 リメイク:$_SESSIONをZend_Session_Namespaceに置き換えた。
6/10 20:50-21:10 viewをsmartyにしたので差し替えた。
8/14 18:00-18:20 『function isTokenValid($namespace = "", &$vars, $mode, $userFlg = true) {』の『$mode_ary = explode(',', 'ins_do,upd_do,del_do' ); // トークンチェック対象モード配列』を『$mode_ary = explode(',', 'ins_do,upd_do,del_do,up_csv' ); // トークンチェック対象モード配列』にした。(ファイルアップロードのときもトークンチェックすることにした。) 。『■使い方はこんな感じ』の内容を最新のものにした。
9/23 17:00-17:30

if (TokenHandle::isTokenValid($this->_getAdminKbn(), strtolower($this->_o['mode']), 
$this->_getAdminKbn() == AppConst::VAL_USER) == false) { // 管理者側トークンチェック
を
if (TokenHandle::isTokenValid($this->_getAdminKbn(), $this->_o, strtolower($this->_o['mode']), 
$this->_getAdminKbn() == AppConst::VAL_USER) == false) { // 管理者側トークンチェック
に変更した