携帯の固有IDのみで認証
Authコンポーネントによる認証は、通常はusersのusernameとpasswordの照合で行うので、この2項目の登録が必須*1ですが、
携帯の固有IDの登録のみで認証を通す方法もありました。
(追記:1/20 22:32 id:ockeghemさんからのご指摘を受けて、IPチェックの必要性について追記しました。)
まず、前提として、usersが以下のような内容になっているとします。
mysql> SELECT id, name, username, password, mobile_id FROM users WHERE id=2\G *************************** 1. row *************************** id: 2 name: Cake username: password: mobile_id: eecca936b0ef58ba3ad38ba924b89a69e0a151b4 1 row in set (0.00 sec)
このユーザは、username/passwordの登録がありません*2。
代わりにmobile_idに、暗号化した固有ID*3が保存されています。
このユーザを認証するためのメソッドは、こんな感じになります。
function mobile_login() { $auth = $this->AuthorizedByMobileID(); if ($auth) { $this->redirect('/m/'); } else { $this->errorMsg = 'この携帯は登録されていません。'; } $this->disp_mobile_error(); } /* 端末IDで認証発行 */ function AuthorizedByMobileID() { $this->set_mobile_uid(); $this->User->primaryKey = 'mobile_id'; return $this->Auth->login($this->Auth->password($this->agent->getUID())); }
要はこの2行。
$this->User->primaryKey = 'mobile_id';
UserモデルのprimaryKey設定を、mobile_idに書き換え、
return $this->Auth->login($this->Auth->password($this->agent->getUID()));
$this->Auth->login()に、
- 暗号化した($this->Auth->password())
- 固有ID($this->agent->getUID())
の文字列を渡します。
usersに固有IDが登録されていればtrue, されてなければfalseを返すので、それに応じてアクションソッド mobile_login()で、リダイレクト処理を実行。
$this->Auth->login($data)処理について
$this->Auth->login($data)の実行で認証発行が可能なことは、CookBookにも記載されています。
http://book.cakephp.org/ja/view/388/login
通常は、$dataに、$this->data由来の
$data = array( 'Users' => array( 'username' => 'admin', 'password' => 'b9fec6e1801150203530ac4f8fa385218d6ee6ff', ) );
のような配列を渡すのが一般的ですが、
$dataは、array型の他、オブジェクトや文字列を渡すことも可能です。
$dataにオブジェクトを渡した場合は、そのオブジェクトから$data->read()で、上記のようなユーザ情報配列を取り出し、usersにusernameとpasswordが合致するユーザがいれば認証OK。
$dataに文字列を渡した場合は、$Auth->primaryKeyで設定されたusersのカラム(デフォルトでid)が$dataと一致するユーザで認証OK、という仕組みになっています。
今回は、この「文字列渡し」を使用しました。
[参考]cale/libs/controller/components/auth.php 823行目 indentify()の一部
} elseif (!empty($user) && is_string($user)) { $model =& $this->getModel(); $data = $model->find(array_merge(array($model->escapeField() => $user), $conditions)); if (empty($data) || empty($data[$this->userModel])) { return null; } }
固有IDの取得について
なお、$this->set_mobile_uid()は、PEARのNet_UserAgent_Mobileを使用するメソッド。
$this->agentに端末情報をセットして、固有ID取得のエラー処理(含むエラー画面遷移)を行っていますが、ここでは詳細省略します。
Net_UserAgent_Mobileの使い方参考
CakePHP 携帯専用サイトを作成する | Sun Limited Mt.
CakePHP その20 〜1.2RC2でPC&携帯対応サイトを考えた 〜:sandmanの旅行の写真”とか”:So-netブログ
他、認証引継ぎなど
上記ソースでは省略していますが、携帯用にセッション引継の改修を別途入れています。
参考
http://d.hatena.ne.jp/hetima/20070201/1170313526
http://www.happytrap.jp/blogs/2009/03/24/797/
CakePHPで ?guid=ONを常にURLに入れる - 趣味の延長線 ←手前味噌 ^^;
(追記)運用上の注意
(ブックマークにて、id:ockeghemさんからのご指摘を受けて追記しました。ありがとうございました。)
以上、固有IDのみで認証を行う方法について記載しましたが、
実際に公開運用する際には、必ず「携帯電話からのアクセスであること」をチェックして、異なる場合はエラーで停止させる機能が別途必要になります。
理由については、以下のサイトで説明されていますが、
要約すると理由は、「固有IDは、ツールなどを使えば偽装できるから」です。
固有ID情報が流出した場合、携帯電話以外からのアクセスを許可していると、悪意の第三者にハッキングされる恐れがあります。
第2回 携帯キャリアと端末を判別する:【PHPで作る】初めての携帯サイト構築|gihyo.jp … 技術評論社
具体的には、「アクセス元のIPをチェックして、各携帯電話会社のサーバ(ゲートウェイ)のIPと照合、合致しなければエラー」という処理となります。
この先、また少し長くなるので、別記します。