DBObjectを利用してユーザー認証システムを構築するチュートリアル。Login失敗時のエラーメッセージ出力部の作成

PHP Evo

DBObjectチュートリアル ユーザー認証システムの作成 (9)

ProEvo > PHP Evo > DBObjectチュートリアル > ログインエラーメッセージの出力

ユーザー認証システムを作成するチュートリアル。ここではLogin失敗時にエラーを出力する機能を作成する。


1 Overview
2. 機能追加
2.1 jWebUnitテストの作成
2.2 ライブラリの変更
2.3 ソースの変更

1 Overview

前回のページでログインフォームを作成しましたが、ログインが失敗したときの処理はありませんでした。
今回の変更でログイン失敗時の処理を追加します。
具体的には、ログイン失敗したときにエラーメッセージが正常に表示されるようにします。

2. 機能追加

2.1 jWebUnitテストの作成

jWebUnitを使って正しいエラーメッセージが書いてあるかどうかをチェックします。
なお、日本語を使うのでエンコードを日本語にする処理を追加しています。 ソースは次のようになります。

aglAuthTest.java
import junit.framework.TestSuite;
import net.sourceforge.jwebunit.*;

/*
 * $Id: auth1-09.html 2 2007-02-28 14:35:40Z atsushifx $
 * 作成日: 2003/12/19
 */

/**
 * @author Furukawa Atsushi 
 */
public class aglAuthTest extends WebTestCase {
  TestContext context;

  public aglAuthTest(String name) {
    super(name);
  }

  protected void setUp() throws Exception {
    context = getTestContext();
    context.setEncodingScheme("Shift_Jis");
    context.setBaseUrl("http://agartha/~atsushifx/aglAuth/admin/");
  }

  public static void main(String[] args) {
    junit.textui.TestRunner.run(new TestSuite(aglAuthTest.class));
  }

  public void testNoLogin()
  {
    beginAt("menu.php");
    assertFormPresent();
    assertFormElementEmpty("userid");
    assertFormElementEmpty("password");
    assertFormElementPresent("login");
    assertFormElementPresent("cancel");
  }

  public void testLoginError()
  {
    beginAt("menu.php");
    // 初期(ユーザーID,パスワード未入力)
    submit();
    assertTextInTable("errmsg", "ユーザーIDを入力してください");
    assertTextInTable("errmsg", "パスワードを入力してください");

    // ユーザーIDのみ入力
    setFormElement("userid", "agl");
    setFormElement("password", "");
    submit();
    assertTextNotInTable("errmsg", "ユーザーIDを入力してください");
    assertTextInTable("errmsg", "パスワードを入力してください");

    //
    setFormElement("userid", "");
    setFormElement("password", "aa");
    submit();
    assertTextInTable("errmsg", "ユーザーIDを入力してください");
    assertTextNotInTable("errmsg", "パスワードを入力してください");

    // 存在しないユーザー
    setFormElement("userid", "agl");
    setFormElement("password", "aa");
    submit();
    assertTextInTable("errmsg", "ユーザーが存在しません");

    // パスワード間違い
    setFormElement("userid", "guest  ");
    setFormElement("password", "_");
    submit();
    assertTextInTable("errmsg", "パスワードが違います");

    // 権限なし
    setFormElement("userid", "guest  ");
    setFormElement("password", "guest");
    submit();
    assertTextInTable("errmsg", "権限がありません");

    //ログイン成功
    setFormElement("userid", "mikoto  ");
    setFormElement("password", "hiruko ");
    submit();
    assertTableNotPresent("loginForm");
  }
}
		

2.2 ライブラリの変更

1.1では、エラーメッセージは"errmsg"という名前のテーブルの要素となることになっています。
これにあわせ、出力テーブルにIDを出力するようにします。
まずはユニットテストを変更します。
ソースは次のようになります。

Tests/formInputTest.php
  /**
  * エラーメッセージ出力テスト(HTML)
  */
  function testToHTML()
  {
    $this->formin->clearError();
    $output = $this->formin->toHTML();
    $this->assertEquals(null, $output, "no message");
    $err = $this->formin->isError();
    $this->assertFalse($err, "no error");

    $this->formin->clearError();
    $this->formin->setError("テストメッセージ");
    $err = $this->formin->isError();
    $this->assertTrue($err, "with error");
    $output_org = "<table id=\"errmsg\" class=\"errmsg\">
  <tr><td class=\"errmsg\"><font color=\"red\">テストメッセージ</font></td><tr>
</table>\n";
    $output = $this->formin->toHTML();
    $this->assertEquals($output_org, $output, "with error message");
  }
		
上記のテストが通るようにライブラリのソースを変更します。
ソースは次のようになります。
aglib/formInput.inc
.
.
  /**
  * エラーメッセージ一覧を取得する(テキスト版)
  * @return string 出力するエラーメッセージ
  */
  function toHTML()
  {
    if (!isset($GLOBALS[$this->_error_buff_id]))  return null;
    $buff = $GLOBALS[$this->_error_buff_id];
    if ($buff == null)  return null;
    $output = "<table id=\"errmsg\" class=\"errmsg\">\n";
    for ($i=0; $i<count($buff); $i++) {
      $output .= "  <tr><td class=\"errmsg\"><font color=\"red\">". $buff[$i] . "</font><td><tr>\n";
    }
    $output .= "</table>\n";
    return $output;
  }
.
.
		
テスト結果が下図のようになれば変更は終了です。
[テスト結果]

2.3 ソースの変更

認証システムのソースを次のように変更します。

aglAuth.inc
  /**
  * ログインフォームを表示する
  */
  function loginForm()
  {
    $PHP_SELF = $_SERVER["PHP_SELF"];
    $form = new formCreator();
    if (isset($_REQUEST["userid"]))   $userid = $_REQUEST["userid"];
    else                              $userid = null;
    ?>
    <div align="center"
    <table border="0" id="loginForm">
    <?php
    if ($this->_formin->isError()) {
      ?>
      <tr>
        <td>
          <?= $this->_formin->toHTML(); ?>
        </td>
      </tr>
      <?php
    }
    ?>
    <tr><td><form method="post" action="<?= $PHP_SELF; ?>">
        <table class="loginForm">
        <tr>
          <td align="right">ユーザーID</td>
          <td><?= $form->toText("userid", $userid, 20); ?></td>
        </tr>
        <tr>
          <td align="right">パスワード</td>
          <td><input type="password" name="password" size="20" value=""></td>
        </tr>
        <tr>
          <td colspan="2" align="right">
            <input type="submit" name="login"  value="ログイン">
            <input type="button" name="cancel" value="キャンセル">
          </td>
        </tr>
        </table>
      </form>
    </table>
    <?php
  }
		

テストを実行します。結果がグリーンバーになれば機能追加は終了です。
[テスト結果]

以上でログインエラーの処理は終了です。
Archivesでテストソースがダウンロードできますので、興味のあるかたは見てください。


$Revision: 2 $
Last update: $Date: 2007-02-28 23:35:40 +0900 (豌エ, 28 2譛 2007) $