CakePHPで携帯サイトを作る - ログインページ(1)の続きです。

ログイン処理のサンプルです。

Index

  1. ログイン用ビュー作成
  2. ログイン用コントローラー作成
  3. 携帯から接続しているユーザーの端末IDチェック
  4. セキュリティに関して
  5. ブラウザ表示サンプル
  6. ダウンロード
  7. リンク(携帯サイトのセキュリティ関連)

ログイン用ビュー作成

PCサイト用のログイン画面のビュー(app/views/login/index.ctp)を作成します。

app/views/login/index.ctp 抜粋
PHP:
  1. <?php
  2. echo $form->create('User',array('url'=>$this->webroot . 'login/index'));
  3. echo $form->input('username',array('label'=>'ユーザーID','div'=>false));
  4. echo $form->input('password',array('label'=>'パスワード','div'=>false));
  5. echo $form->end('ログイン');
  6. ?>

携帯サイト用のログイン画面のビュー(app/mobile_views/login/index.ctp)を作成します。

app/mobile_views/login/index.ctp 抜粋
PHP:
  1. <?php
  2. <div>
  3.   <form method="post" action="<?php echo $this->webroot; ?>login" enctype="application/x-www-form-urlencoded">
  4.     ユーザーID<br />
  5.     <input name="data[User][username]" type="text" maxlength="128" value="" id="UserUsername" /><br />
  6.     パスワード<br />
  7.     <input type="password" name="data[User][password]" value="" id="UserPassword" /><br />
  8.     <input type="submit" value="ログイン" />
  9.   </form>
  10. </div>
  11. ?>

携帯サイト用の簡単ログイン用のビューも作成します。

app/mobile_views/login/easy.ctp 抜粋
PHP:
  1. <?php
  2. if (!empty($already_login)) {
  3.   echo '<p>ログイン済みです。</p>';
  4. }
  5. if (!empty($empty_serial_number)) {
  6.   echo '<p>端末IDを送信してください。</p>';
  7. }
  8. if (!empty($not_found)) {
  9.   echo '<p>登録されていません。</p>';
  10. }
  11. if (!empty($unset_easy_logon)) {
  12.   echo '<p>簡単ログインできるように設定していません。通常のログイン後、設定してください。</p>';
  13. }
  14. ?>

ログイン用コントローラー作成

Authコンポーネントを利用したかったのですが・・・。
ログインの処理は、単純なものにします。

app/controllers/login_controller.php 抜粋
PHP:
  1. class LoginController extends AppController
  2. {
  3.   function _login()
  4.   {
  5.     $username = $this->data['User']['username'];
  6.     $password = $this->data['User']['password'];
  7.  
  8.     $ret = $this->User->checkLogin($username,$password);
  9.     if ($ret !== false) {
  10.       $sess_data = array();
  11.       $sess_data[SESS_USER_ID] = $ret['id'];
  12.       $sess_data[SESS_USER_ROW] = $ret;
  13.       $this->Session->write(SESS_AUTH_INFO,$sess_data);
  14.       $this->redirectPage($this->webroot);
  15.     }
  16.     return $ret;
  17.   }
  18.  
  19.   function index()
  20.   {
  21.     if ($this->isLogin()) {
  22.       $this->set('already_login',true);
  23.       return;
  24.     }
  25.  
  26.     if ($_SERVER["REQUEST_METHOD"] == "POST") {
  27.       if (!$this->_login()) {
  28.         $this->set('login_fail',true);
  29.       }
  30.     }
  31.   }
  32.  
  33.   function easy()
  34.   {
  35.     if (!IS_MOBILE) {
  36.       $this->redirect($this->webroot . 'login');
  37.       return;
  38.     }
  39.  
  40.     if ($this->isLogin()) {
  41.       $this->set('already_login',true);
  42.       return;
  43.     }
  44.  
  45.     if (!MOBILE_SERIAL_NUMBER) {
  46.       $this->set('empty_serial_number',true);
  47.       return;
  48.     }
  49.     // サンプルなので端末IDのみで行を取得。予定としては端末IDとキャリア名(docomo,au,softbankなど)で検索する。
  50.     $row = $this->User->findBySerialNumber(MOBILE_SERIAL_NUMBER);
  51.     if (empty($row['User'])) {
  52.       $this->set('not_found',true);
  53.       return;
  54.     }
  55.     if (empty($row['User']['easy_logon'])) {
  56.       $this->set('unset_easy_logon',true);
  57.       return;
  58.     }
  59.  
  60.     $sess_data = array();
  61.     $sess_data[SESS_USER_ID] = $row['User']['id'];
  62.     $sess_data[SESS_USER_ROW] = $row['User'];
  63.     $this->Session->write(SESS_AUTH_INFO,$sess_data);
  64.     $this->redirectPage($this->webroot);
  65.   }
  66. }

携帯から接続しているユーザーの端末IDチェック

携帯から接続したユーザーがログイン後、自分のプロフィールなどを見るページ・変更するページなどに遷移するときは、端末IDを送信してもらうことにします。
送信してもらった端末IDとログイン時にデータベースから取得してセッションに記憶した端末IDと比較します。
それが違ったら、不正とし、再ログインを促すページへ移動するようにします。

app/app_controller.php 抜粋
PHP:
  1. function checkLoginMobileId($redirect=true)
  2.   {
  3.     if (IS_MOBILE == false) {
  4.       return true;// 携帯端末からの接続でない
  5.     }
  6.     if (!MOBILE_SERIAL_NUMBER) {
  7.       // 端末IDを取得できていない
  8.       if ($redirect) {
  9.         $this->redirectPage($this->webroot . 'sorry/number');
  10.       }
  11.       return false;
  12.     }
  13.     $s = $this->Session->read(SESS_AUTH_INFO);
  14.     if (empty($s[SESS_USER_ID])) {
  15.       // ログインした情報がセッションにない
  16.       if ($redirect) {
  17.         $this->redirectPage($this->webroot . 'login');
  18.       }
  19.       return false;
  20.     }
  21.     if (MOBILE_SERIAL_NUMBER != $s[SESS_USER_ROW]['serial_number']) {
  22.       $this->log('セッション内の端末IDと取得できた端末IDが違う');
  23.       $this->Session->delete(SESS_AUTH_INFO);
  24.       if ($redirect) {
  25.         $this->redirectPage($this->webroot . 'sorry/relogin');
  26.       }
  27.       return false;
  28.     }
  29.     return true;
  30.   }

セキュリティに関して

特に携帯用のページを表示する場合、追加のセキュリティ対策が必要です。

このサンプルでは、ドコモの携帯端末から接続されていると判断した場合、セッションIDをURLに付加するようにしています。
URLを見るとセッションIDがわかります。

なんらかの方法でセッションIDを取得した人は、そのセッションIDを付与されているユーザーになりすませます。
なりすましによる被害を防ぐため、本サンプルでは、携帯から接続しているユーザーの端末IDチェックをしています。

しかし、端末IDを偽装できるならば、端末IDのチェックだけでは不十分です。
他人にセッションIDを知られないとしても、このサンプルの簡単ログインを有効にしている場合、偽装した端末IDがあれば、その端末IDをもつユーザーになりすましてログインできてしまうのです。

端末IDをチェックする他に、IPアドレスでキャリアを制限するなどの複数のセキュリティ対策を施す必要があります。

PCサイトも必要に応じて、不正防止策を追加する必要があります。

ブラウザ表示サンプル

Firefoxで接続すると、ログイン後のトップページは、次のような表示となります。

Firefox表示サンプル

iモードHTMLシミュレータⅡの場合は、次のような表示です。

携帯表示サンプル

シミュレータ以外にドコモとソフトバンクの実機で表示を確認しています。
auの実機では表示を確認していません。

ダウンロード

アーカイブへのリンクを「ダウンロード(「CakePHPで携帯サイトを作る」のサンプル)」に移動しました(2009/02/11)。

リンク(携帯サイトのセキュリティ関連)

携帯サイトのセキュリティに言及しているサイトへのリンクです。参考にさせていただきました。

関連投稿

Tags: ,

コメントをどうぞ