トランザクショントークン

トランザクショントークンの生成/チェック機能を実装してみる。この機能はMoony 0.8.1で追加される予定。

Moony_Tokenというクラスを新たに追加、メソッドを2つ用意する。

  • generate(&$session, &$response)
    • セッションが開始されている場合
      • ランダムな文字列でトークンを生成
      • 生成したトークンをセッションに保存
      • 生成したトークンをResponseに属性として追加
      • 無条件にtrueを返す
    • セッションが開始されていない場合
      • 何もせずにfalseを返す
  • check(&$request)
    • セッションが開始されていない場合
      • 無条件にfalseを返す
    • リクエストパラメータとしてトークンが送信されてこない場合
      • 無条件にfalseを返す
    • セッションが開始されていて、トークンが送信されてきた場合
      • セッションから保存しておいたトークン値を取得
      • 直ちにセッションからトークン値を削除
      • リクエストパラメータとして送信されてきたトークン値と保存しておいた値を比較
        • 合致する場合trueを返す
        • 合致しない場合falseを返す

Moony_Config.phpに設定追加

define('MOONY_TRANSACTION_TOKEN_NAME', 'transaction_token');

Moony_Tokenの実装:

class Moony_Token
{
  function generate(&$request, &$response)
  {
    $session = $request->getSession();
    if ($session->hasStarted()) {
      $token = md5(uniqid(rand(), true));
      $session->set(MOONY_TRANSACTION_TOKEN_NAME, $token);
      $response->set(MOONY_TRANSACTION_TOKEN_NAME, $token);
      return true;
    }
    return false;
  }
  function check(&$request)
  {
    $session = $request->getSession();
    if (!$session->hasStarted()) {
      return false;
    }
    if (!$request->exists(MOONY_TRANSACTION_TOKEN_NAME)) {
      return false;
    }
    $saved = $session->get(MOONY_TRANSACTION_TOKEN_NAME);
    $session->remove(MOONY_TRANSACTION_TOKEN_NAME);
    if ($request->get(MOONY_TRANSACTION_TOKEN_NAME) == $saved) {
      return true;
    }
    return false;
  }
}

フォームの記述例:

<form>
  <input type="hidden"
     name="transaction_token" value="{$transaction_token}" />
</form>

アクションクラスでチェックを行う場合:

class FooAction extends Moony_Action
{
  function execute($request, $response)
  {
    if (Moony_Token::check($request)) {
      // check success
    } else {
      // check failure
    }
  }
}

※2006-02-28に一部内容を修正しました。