Home > Archives > 2007-06

2007-06

ログイン処理をつきつめて考えてみる(CakePHP修行 #017)

さて次に何をすべきか迷いましたが、ログイン処理をいろいろやってみたいと思います。

実現したい機能は以下のとおり。

  1. セキュリティを高めたい(悪意のあるコード入力の阻止、md5とか使ってなんか?)。
  2. エラーになった場合、前回入力したメアドは保持したい。
  3. 「情報を保存する」機能の実装。
  4. 「パスワードを忘れた場合」の処理。
  5. クリックしたURLを保持しておいて、ログイン後にHomeじゃなくて、そのURLに行くように処理。

ちょっとした機能ではありますが、なんかノー・アイデアですなw。ここらへんでもう一度レファレンスを読み返したいと思います。

次の更新はいつかなぁ・・・週末にもう一回ぐらいかな。お楽しみに。

※ CakePHP修業は百式管理人がSNSっぽいものをCakePHPで作ろうとして挫折するまでの日記です。前回までのあらすじはこちらへ。

ログアウト処理をやってみる(CakePHP修行 #016)

さて次はログアウト処理。これは簡単っぽい。

/app/controllers/users_controller.phpに次の記述を追加。

  function logout()
  {
    $this->Session->delete('my_id');
    $this->redirect('/users/home/');
  }

で、ログアウトリンクには /home/users/logout を設定。クリックしてみます。

home.gif

↑ 右上のログアウトをクリックして・・・。

login_updated.gif

↑ ログアウトできましたー。

ログアウトついでにもう一つのテストアカウントでログイン。

home_akiyan.gif

↑ こちらもOK。ちゃんとユーザーが切り替わっていますね(表示名がakiyanになりました)。

さてさて、今回は簡単でしたね。次はプロフィール編集に行くか、ログイン処理を作りこんでいくか・・・どっちにしようかなー。

※ CakePHP修業は百式管理人がSNSっぽいものをCakePHPで作ろうとして挫折するまでの日記です。前回までのあらすじはこちらへ。

ホーム画面もカスタマイズしたい(CakePHP修行 #015)

前回まででログイン画面がカスタマイズできたので勢いにのってホーム画面もカスタマイズ。

/app/views/layout/home.thmlを作って変数を埋め込んでいきます。

<div id="my_page" class="clear" style="border:4px solid #ececec">
<h2><a href="/users/home/"><?php echo $me['User']['name']; ?></a></h2>
<div id="contents">
<div id="menu" class="clear">
<ul>
<li><a href="/users/home">Home</a></li>
<li><a href="">Diary</a></li>
<li><a href="">Friends</a></li>
<li><a href="/users/edit/">Settings</a></li>
<li><a href="/users/logout/">Logout</a></li>
</ul>
</div><!-- /menu -->
<h3>My Profile</h3>
<div id="my_profile" class="clear">
<img src="100shiki.jpg" width="50" height="50" border="0" alt="" />
<p><?= $me['User']['profile']; ?></p>
</div>
</div>
</div>

こんな感じかな・・・。

で、ログイン。

home.gif

↑ おー!やったぜ!

ちょっとわかりにくいですが、きちんとユーザー名が表示されていますね。今のところプロフィールには何も入っていないので空白でOKかと。プロフィール画像をどうするか、とか考えるところは多々ありますが、まぁ、今のところはこれで。

さて次はログアウト処理でもやってみますかね。

※ CakePHP修業は百式管理人がSNSっぽいものをCakePHPで作ろうとして挫折するまでの日記です。前回までのあらすじはこちらへ。

画面をカスタマイズしたい(CakePHP修行 #014)

さて今回は画面のカスタマイズをします。参考にしたのはこちら。

» CakePHP Manual

いくつかポイントがありそうです。

  • /app/views/layout/default.thtmlを作ればそれがデフォルトのレイアウトを上書きしてくれるらしい。
  • titleタグの中身はcontroller中に$pageTitleで指定すればいけるらしい(つか、レイアウト中の変数をControllerで指定できるつうことか)
  • レイアウトは複数作って$layoutで切り替えられるらしい。
  • レイアウト中の小さなパーツは/app/views/elementsに入れておいて使い回しできるらしい。

なるほど。つうことで以下をやってみます。

  • /app/views/layout/default.thtmlを作って以前作ったレイアウトを適用させます。
  • ページタイトルを適宜変更します(LoginとMy Homeかな)。
  • $layoutの切り替えをしたいので、なにかでテストします。
  • ヘッダーとフッターは/app/views/elementsにいれてレイアウト中から使ってみます。

■ やってみた結果

前回までのログイン画面はこんな感じでした。いけてません。

login_1.gif

↑ ま、デフォルトですね。

そこで/app/views/layout/default.thtmlを作ってみます。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="keywords" content="">
<meta name="description" content="">
<link rel="stylesheet" href="/css/core.css" type="text/css" />
<link rel="shortcut icon" href="/favicon.ico" />
<title><?php echo $title_for_layout?></title>
</head>
<body>
<div id="container" class="clear"> 
<div id="header" class="clear">
<h1><a href=""><img src="/img/codexcode_logo.png" width="400" height="50" border="0" alt="" /></a></h1>
</div>
<?php echo $content_for_layout ?>
</div><!-- end of container -->
<div id="footer">
<p>Copyright 2007 code*code.com, All rights reserved.</p>
</div>
</body>
</html>

それから必要なCSS、画像は/app/webroot以下に配置します。そしておもむろにhttp://www.codexcode.com/にアクセス!

login_updated.gif

↑ キタコレ!

そしてuser_controller.phpのlogin()に$pageTitleを入れてみます。

  function login()
  {
    $this->pageTitle = 'Welcome to CODE*CODE!';
    $this->set('error', false);

そしてアクセスすると確かにタイトルタグが変更されました。これは問題なし。

次にヘッダーとフッターをelementにしてみたいと思います。/app/views/elements/header.thtml、/app/views/elements/footer.thtmlを作ってみます。そしてdault.thtmlの方には次のように記述。

<div id="container" class="clear"> 
<?php echo $this->renderElement('header'); ?>
<?php echo $content_for_layout ?>
</div><!-- end of container -->
<?php echo $this->renderElement('footer'); ?>

そんでもってアクセス。これもうまくいったっぽいです。elementsでは変数とか渡せるようですが、それは後々使うことにしましょう。

■ レイアウトの切り替えがわからない

さてここまでは順調ですが、ちょっとはまった点(そしてまだ解決していない)。

わからないのはsetLayout()の使い方。マニュアル上ではレイアウトファイルを複数作って切り替えることが可能、とあります。そこでLogin中は/app/views/layout/login.thtmlを使いたいと思い、次のように記述しました。

  function login()
  {
    $this->setLayout('login');
    $this->pageTitle = 'Welcome to CODE*CODE!';
    $this->set('error', false);

すると・・・。

login_error.gif

↑ なんかエラー・・・なぜだ?

とんでもないケアレスミスのような気がしないでもないですが・・・まぁ、恥をかくのが修行の目的なんでさらしておきます・・・。もちょっと調べてわかったら報告しますね。

しかし今のところ特に必要な機能でもないので、問題解決に飽きたら次のステップに進んじゃいますw。

※ CakePHP修業は百式管理人がSNSっぽいものをCakePHPで作ろうとして挫折するまでの日記です。前回までのあらすじはこちらへ。

トップ画面を指定したい(CakePHP修行 #013)

さてCakePHP。前回までのあらすじはこちら。

» CakePHP修行! アーカイブ | i d e a * i d e a

前回まででなんとなくログインがうまくいきました。で、できれば http://www.codexcode.com/ にアクセスしたときに http://www.codexcode.com/users/home/ になってほしいのでそのように設定してみます。

参考にしたのはこちら。

» A.13. Routes(ルート)

これを使えばうまくできそうです。早速/app/config/routes.phpを変更してみます。

$Route->connect('/', array('controller' => 'users', 'action' => 'home'));

テストしてみると思ったように動作してくれているようです。簡単ですね。

さて次はテンプレートのカスタマイズですね。さて、どっから調べるか・・・。

ログイン画面をデバッグする(CakePHP修行 #012)

さてCakePHP。前回までのあらすじはこちら。

» CakePHP修行! アーカイブ | i d e a * i d e a

で、前回まででログイン画面をざっくり動作させようとしたのですが、なんだかエラーが出てうまくいきませんでした。

うっかり「CakePHP修行終了~」エントリーを書こうと思いましたがw、青い人がフォローしてくれたので続けたいと思います。ありがとう!青い人。すごい勉強になっている!

ちなみにつっこんでもらったエントリーはこちら。

» Re: CakePHP修行 #011 無限リダイレクトに気をつけろ : akiyan.com

ポイントはいくつか。

  • 「ブラウザの不正リダイレクトは無限ループが原因」ってことが多いらしいことを知りました。
  • ControllerのbeforeFilter()の挙動について学んだ。
  • 解決方法についてアイディアをもらった。

うむ。かなりのぽかミスにもかかわらず「よくあるミス」となぐさめてくれた青い人に感謝感激。教え上手ですな。さすが開発チームのリーダー。

ではでは気を取り直していってみます。

■ 今回の作業計画

いろいろ考えた結果、今回は以下をやってみます。

  • 前回のエラーに関しては単純にbeforeFilterを使わずに、ログインが必要なアクションについてその都度checkSession()を呼ぶようにしたいと思います。
  • 現在Sessionに保存されている情報は’User’で、User情報全部なのですが、IDだけでいいだろ、ということで’my_id’をログイン後にセッションに保存するようにします。そうしないとユーザー情報が変わった時に全部セッション書き換えないといけないので。
  • users_controllerにhome()を足します。home()は自分のホーム画面を表示するためのものです。
  • http://www.codexcode.com/にアクセスすると自分のホーム画面に行くように設定してみます。
  • ヘッダーとフッターのテンプレートを変更して画面をかっこよくします。

さてがしがしやりましょう。

■ セッション関連、home()など

まずはController。beforeFilter()を削除し、ログインの挙動を変更し、home()を追加します。

/app/controllers/users_controller.phpは以下のように。

  function home ()
  {
    $this->checkSession();
    $this->set('me', $this->User->findById($this->Session->read('my_id')));
  }
  function login()
  {
    $this->set('error', false);
    if (!empty($this->data))
    {
      $someone = $this->User->findByEmail($this->data['User']['email']);
      if(!empty($someone['User']['pwd']) && $someone['User']['pwd'] == $this->data['User']['pwd'])
      {
        $this->Session->write('my_id', $someone['User']['id']);
        $this->redirect('/users/home/');
      }
      else
      {
        $this->set('error', true);
      }
    }
  }

セッションの変更に合わせて/app/app_controller.phpも変更。

<?php
class AppController extends Controller
{
    function checkSession()
    {
        // If the session info hasn't been set...
        if (!$this->Session->check('my_id'))
        {
            // Force the user to login
            $this->redirect('/users/login');
            exit();
        }
    }
}

viewも追加しないといけませんね。/app/views/users/home.thtmlも作ります。とりあえずデータをDumpするだけで。

<?php
  var_dump ($me);

ここまでを一気に完了。テストしてみます。

まずは /users/home/ にアクセス。

login_1.gif

↑ ちゃんとログイン画面がでました!

login_3.gif

↑ 無事ログインすると自分の情報が!

さて、次はURLの挙動とテンプレートについて作業してみます。長くなるのでエントリーわけよっと。

ログイン画面を作っていくぞ、と(CakePHP修行 #011)

さてCakePHP。前回までのあらすじはこちら。

» CakePHP修行! アーカイブ | i d e a * i d e a

今回はログイン画面を作っていきます。参考にするのはここらへん。

» CakePHP Manual

■ /app/views/users/login.thtml

まずはログイン画面を作ります。チュートリアルを参考にしながら作りこんでいきます。

前回のモックアップで作った画面のHTMLはこんな感じなのでここにコードを入れこんでいきます(テーブルタグかよー、とか言わないw)。

<form>
<div id="sys_msg">email and password do not match!</div>
<table border="0" cellspacing="2" cellpadding="2">
<tr><td width="40%" align="right">email</td><td><input type="text" size="30" name="email" value="" /></td></tr>
<tr><td width="40%" align="right">password</td><td><input type="password" size="20" name="password" value="" /></td></tr>
<tr><td width="40%">&nbsp;</td><td><input type="checkbox" name="save" value="" /> save my info?</td></tr>
<tr><td width="40%">&nbsp;</td><td><input type="submit" value="Let me in!" /></td></tr>
<tr><td width="40%">&nbsp;</td><td><a href="">forgot your password?</a></td></tr>
</table>
</form>

チュートリアルによれば「$html->url」とか「$html->input」とかいれていけばいいらしい。あまり考えずにやってみます。

<form action="<?php echo $html->url('/users/login'); ?>" method="post">
<?if ($error): ?>
<div id="sys_msg">email and password do not match!</div>
<? endif; ?>
<table border="0" cellspacing="2" cellpadding="2">
<tr><td width="40%" align="right">email</td><td><?php echo $html->input('User/email', array('size' => 30)); ?></td></tr>
<tr><td width="40%" align="right">password</td><td><?php echo $html->input('User/pwd', array('size' => 20)); ?></td></tr>
<tr><td width="40%">&nbsp;</td><td><input type="checkbox" name="save" value="" /> save my info?</td></tr>
<tr><td width="40%">&nbsp;</td><td><?php echo $html->submit('Let me in!'); ?></td></tr>
<tr><td width="40%">&nbsp;</td><td><a href="">forgot your password?</a></td></tr>
</table>
</form>

うーん、と。「save my info?」のところをどう処理したらいいかわかりません。checkboxの表現もわからなければ、データとしてどう持つべきかもよくわかりません。そういうときは「ザ・後回し!」。とりあえずチェックボックスだけ表示させておいて機能はあとで作るようにします。

■ /app/controllers/users_controller.php

次にControllerでlogin()を作ります。チュートリアルをコピーして適宜変えてみます。長くなるのでコード内のコメントは削除。

<?php
class UsersController extends AppController
{
  function login()
  {
    $this->set('error', false);
    if (!empty($this->data))
    {
      $someone = $this->User->findByEmail($this->data['User']['email']);
      if(!empty($someone['User']['pwd']) && $someone['User']['pwd'] == $this->data['User']['pwd'])
      {
        $this->Session->write('User', $someone['User']);
        $this->redirect('/');
      }
      else
      {
        $this->set('error', true);
      }
    }
  }
  function logout()
  {
    $this->Session->delete('User');
    $this->redirect('/');
  }
}
?>

えーと、これはこれでいいのかな。リダイレクト先をどうすべきかがいまいちわからん。あとpwdはまんまで比較しているのでいまいちですね。これはあとでやることにしましょう。

■ /app/app_controller.php

さて次はセッションをチェックして、ログインしていなかったらログイン画面に飛ばすロジックを作成(かな?)。

<?php
class AppController extends Controller
{
  function checkSession()
  {
    if (!$this->Session->check('User'))
    {
      $this->redirect('/users/login');
      exit();
    }
  }
}
?>

■ /app/controllers/users_controllers.php

そんでもって、User関係のすべてのアクションの前にこのセッションチェックをしてみましょう。

<?php
class UsersController extends AppController
{
  function beforeFilter()
  {
    $this->checkSession();
  }
}

■ テスト!

さて、ここまで出来たらテストです!おもむろに http://www.codexcode.com/users/ にアクセス!

code_error.gif

↑ キターーーーーーーーーーーーーーーーーーーー・・・じゃねー、キテネェ・・・。

しかし http://www.codexcode.com/users/login にはリダイレクトされていますね。/app/views/users/login.thtml があればアクセスできんじゃねぇの?と思うのですが・・・。

しかもエラーメッセージがリダイレクト関係の変なメッセージなのが気になります。

うーん。眠いから寝る。

モックアップ画面をいろいろ作る(CakePHP修行 #010)

さてCakePHPのお勉強。前回までのあらすじはこちら。

» CakePHP修行! アーカイブ | i d e a * i d e a

それから前回までの記事への突っ込みありがとう>青い人!

さて今回はモックアップ画面の作成です。最初は「デザインはチョーてきとーでー」と思ったのですが、開発する上でテンションをあげるにはやはりデザインから。CakePHPと直接関係ないですが、画面のモックアップを作っていきます。

今回とりあえず作るのは次の3画面。作っているうちに課題は見えてくるでしょう。

  • ログイン画面
  • 自分の「ホーム」画面
  • 友達の「ホーム」画面

ま、ちょろちょろと作るので本気度30%ぐらいで。シンプルかつミニマムがコンセプト。あと面倒なんでインターフェースはすべて英語にします(英語のタイポグラフィーのがきれいだから)。

つうわけでつくってみた画面。

■ ログイン画面

ログインしていない状態では全部これが出るようにします。

mock_login.png

↑ とりあえず全表示状態なんでエラーメッセージも出しています。

■ 自分のホーム画面

こんな感じじゃないすかね?(http://www.codexcode.com/かな)

mock_home.png

↑ ま、のちのち足したい機能が出てくるかと思いますがそれはそのとき考えましょう。写真は拝借しても怒りそうにない人から拝借しました。

■ 友達のホーム画面

自分のホーム画面のトップを残しつつ、その下を友達の画面に。わかりやすいかな・・・ま、いいです。ユーザビリティとかそういうのは。とりあえず。

URL的には http://www.codexcode.com/users/25 とかかな。

mock_friends.png

↑ メニュー的にはこんなところでしょ。今思ったけど友達の日記は友達の友達の日記じゃなくて友達の日記一覧だな・・・。

ただのモックアップ画面なんで細かいところは突っ込まないように。設定画面とか日記投稿画面はあとからつくります。今思ったけど日記に対するコメント作りたいな・・・。ま、あとでやりましょう。

■ 次回予告

で、全部つくると大変なんで、とりあえずログインしたら自分のホーム画面に行って自分のプロフィールが表示されるところまで作ってみたいと思います。

問題を違った角度から捉えてみるとシンプルな解決策が浮かんでくる

プログラミングブログみたいになってきたので閑話休題。

Productivity 505のブログに「Beautifully Simple Solutions」「Simple Way to Speed up Elevators」なる記事がありました。

問題を違った角度から捉えてみるとシンプルな解決策が浮かんでくる場合があるよ、という事例です。

他にも思いあたる事例があったので多少うろおぼえがはいってますが、書いてみます。

  • 問題:犯罪が多い地域をどうするか?
  • うまくいかなかった解決策:セキュリティシステムの導入。フルタイムのガードの雇用。

    うまくいった解決策:現役の警察官に無料で住居を提供。→ そこにパトカーがとまっているだけで犯罪が減ったそうです。

  • 問題:エレベーターが来るのが遅い
  • うまくいかなかった解決策:新しい高速エレベータの設置(コストがかかりすぎるので断念)、指定階しか止まらない「エクスプレスエレベータ」の導入。

    うまくいった解決策:エレベータの横に鏡を設置。→ エレベーターを待っている間にすることができたのでイライラしなくなった。

  • 問題:駐輪場の自転車がガタガタで近所迷惑
  • うまくいかなかった解決策:立て看板、注意。

    うまくいった解決策:駐輪場に線を引いた。→ 線をひくと人はその線に沿って自転車をとめるようになった。

  • 問題:工場でミスが多い(アメリカの事例)
  • うまくいかなかった解決策:生産性コンサルタントの起用。

    うまくいった解決策:働いている人の呼び方を「Worker(労働者)」から「Craftsman(職人)」へ変えた。→ 働いている人が誇りを持って仕事ができるようになり、ミスが減った。

三番目の事例は「出会う人みな、仕事の先生」(絶版中・・・現在13,500円って・・)から引用させていただきました。

出会う人みな、仕事の先生

» 出会う人みな、仕事の先生

常にシンプルなソリューションを模索したいですね。

$scaffoldを試してみる(CakePHP修行 #009)

さてCakePHPのお勉強。前回までのあらすじはこちら。

» CakePHP修行! アーカイブ | i d e a * i d e a

さて前回「bake.php=面倒」ということがわかったので(かなり個人的な主観)、今回は$scaffoldをControllerに足す方法を試します。

■ 下準備

試しにやるだけなのでUsersモデルだけでやってみます。イメージでは作業は以下の通り。

  • /app/models/user.phpをつくる
  • /app/controllers/users_controller.phpを作って$scaffoldを追加。
  • /users/にアクセスすれば追加・削除・編集の画面ができているはず!(かな?)

では期待どおりになるかどうか・・・ドキドキしながらやってみます。

■ Usersモデルを作成

/app/models/user.phpを次のように作成。モデルは単数か、覚えないと。まず一つを定義するから、とか覚えておこう。

<?php
class User extends AppModel
{
    var $name = 'User';
}

↑ こんな感じ。最後の「?>」は書かない派ですw。

■ コントローラーをつくるぞ

/app/controllers/users_controller.phpを作ります。こちらは複数ね。

<?php
class UsersController extends AppController
{
    var $name = 'Users';
    var $scaffold;
}

さぁ、これでいいのでしょうかねぇ・・・。できたのか試してみます。

■ /usersにアクセスしてみる

さて・・・と、http://www.codexcode.com/users/にアクセスしてみます。

scaf_1.gif

↑ キターーーーーーー・・・・Warningかよ・・・orz。

前回/app/tmpに777のPermissionを与えましたが、これ、下位フォルダもそうしないとだめっぽかったっすね(つか、当然ですね・・・)。「chmod -R 777 /app/tmp」で解決。

scaf_2.gif

↑ きれいになりました。

なーるほど、これは便利ですね。Viewを書く手間が一気に減りました。うーん、便利かも。

それからマニュアルによるとViewのカスタムも簡単なようです。しかもすべてのモデルに共通するViewも作れるみたい。

各モデルごとなら以下を追加。

/app/views/users/scaffold/index.scaffold.thtml
/app/views/users/scaffold/edit.scaffold.thtml
/app/views/users/scaffold/show.scaffold.thtml
/app/views/users/scaffold/new.scaffold.thtml

すべてのモデルに共通するViewなら以下を追加。

/app/views/scaffold/index.scaffold.thtml
/app/views/scaffold/edit.scaffold.thtml
/app/views/scaffold/show.scaffold.thtml
/app/views/scaffold/new.scaffold.thtml

ちょっと試してみようかと思いましたが、まぁ、将来的に必要になったらやればいいや、ということでScaffoldの実験はこれでおしまい。とりあえずuser_controller.phpから$scaffoldを外しておきます。

さて、やっぱりViewはカスタムで一つずつ作ってみたいので、次回はいよいよ画面のモックアップからViewの設計までいきたいと思います。

Home > Archives > 2007-06

最近の記事
カテゴリー別
過去記事一覧

Return to page top