ユーザ登録(仮登録・メール・本登録)
以前1.3版で投稿した「ユーザ登録」処理の2.x版を作成しました。フローは同じで以下のようにします。
1. メールアドレス・パスワードでユーザ登録
2. この時点では仮登録として、本登録用のURLリンクをメールで送付
3. 送付されたリンクをクリックして「本登録完了(activate)」とする
ユーザ(users) テーブル
statusを用意し、デフォルトを1としています。"1"を仮登録状態でログイン不可、"0"を本登録としログイン可能にします。その制御は、「scope」が使えそうです。
-- usersテーブル
CREATE TABLE IF NOT EXISTS `users` (
`id` INT NOT NULL AUTO_INCREMENT ,
`username` VARCHAR(255) NOT NULL ,
`password` CHAR(128) NOT NULL ,
`status` TINYINT NOT NULL DEFAULT 1 ,
`created` DATETIME NOT NULL ,
`modified` DATETIME NOT NULL ,
PRIMARY KEY (`id`) ,
UNIQUE INDEX `username_UNIQUE` (`username` ASC) )
ENGINE = InnoDB DEFAULT
CHARACTER SET = utf8
COLLATE = utf8_general_ci
COMMENT = 'User';
usernameカラムの長さですが、innoDB+utf8の場合は最長で設定できるのは255になります。(MySQL)
passwordカラムの長さは、使用するハッシュ関数によります。ハッシュ化を参考にして下さい。
Userモデル
confirmPasswordメソッドでパスワードと確認用パスワードの一致の確認を行い、ハッシュ化しています。
独自のバリデーションルールを作成
「isUnique」バリデーション
// app/Model/user.php
<?php
class User extends AppModel {
var $name = 'User';
var $useTable = 'users';
public $validate = array(
'username' => array(
// メールアドレスであること。
'validEmail' => array( 'rule' => array( 'email', true), 'message' => 'アドレスを入力して下さい'),
// 一意性チェック
'emailExists' => array( 'rule' => 'isUnique', 'message' => '既に登録されています'),
),
'password' => array(
// パスワード・確認用パスワードの一致
'match' => array( 'rule' => array( 'confirmPassword', 'password_confirm'), 'message' => '一致しません'),
)
);
public function confirmPassword( $field, $password_confirm) {
if ($field['password'] === $this->data[$this->name][$password_confirm]) {
// パスワードハッシュ化
$this->data[$this->name]['password'] = Security::hash( $plain, 'sha512', true);
return true;
}
}
}
?>
Usersコントローラー
// app/Controller/UsersController.php
<?php
class UsersController extends AppController {
// Authコンポーネント
var $components = array( 'Auth');
public function beforeFilter() {
parent::beforeFilter();
// 非ログイン時にも実行可能とする
$this->Auth->allow( array( 'signup', 'activate'));
}
public function signup(){
}
public function activate(){
}
}
?>
ユーザ登録(signup) ビュー
メールアドレスとパスワードを入力するフォームです。ここでは、それぞれのフォームに意図的にtypeを指定していますが、自動的に付与する場合は以下を参照して下さい。
// app/View/Users/signup.ctp
<?php
echo $this->Form->create( 'User', array( 'type'=>'post', 'url'=>'signup'));
// ユーザ名
echo $this->Form->text( 'username', array( 'maxlength' => '255', 'type' => 'email'));
// パスワード
echo $this->Form->text( 'password', array( 'maxlength' => '50', 'type' => 'password'));
// パスワード確認用
echo $this->Form->text( 'password_confirm', array( 'maxlength' => '50', 'type' => 'password'));
echo $this->Form->end( 'Signup');
?>
signupアクション
// app/Controller/UsersController.php
public function signup() {
if (!empty( $this->data)){
// 保存
if( $this->User->save( $this->data)){
// ユーザアクティベート(本登録)用URLの作成
$url =
DS . strtolower($this->name) . // コントローラ
DS . 'activate' . // アクション
DS . $this->User->id . // ユーザID
DS . $this->User->getActivationHash(); // ハッシュ値
$url = Router::url( $url, true); // ドメイン(+サブディレクトリ)を付与
// メール送信
// return
$this->Session->setFlash( '仮登録成功。メール送信しました。');
} else {
// バリデーションエラーメッセージを渡す
$this->Session->setFlash( '入力エラー');
}
}
}
■passwordのハッシュ化
モデル内でパスワード確認(confirmPassword)の中で行っています。
ハッシュ化についてはここを参照して下さい。
■ユーザアクティベート(本登録)用URLの作成
ここでは、わかりやすく以下のようにしています。
サイトURL/サブディレクトリ/コントローラ/アクション/ユーザID/ハッシュ値
■ハッシュ値の生成
Userモデルに以下を追加して下さい。簡単に言うと更新日時をハッシュ化したものになります。ハッシュ関数はどれを使用するかは自由。(下の例だと'md5')
リンクに時限を設ける場合は、時間locatime()などを付与して、activate時に24時間以上経過している場合は無効にするなどの処理をするという方法もありかもしれません。
public function getActivationHash() {
// ユーザIDの有無確認
if (!isset($this->id)) {
return false;
}
// 更新日時をハッシュ化
return Security::hash( $this->field('modified'), 'md5', true);
}
■メール送信部分は、以下を参照してアクティベート用URLを送信して下さい。
本登録(activate)アクション
ユーザ側に無事メール送付できたところで、本登録を行ってもらいます。
public function activate( $user_id = null, $in_hash = null) {
// UserモデルにIDをセット
$this->User->id = $user_id;
if ($this->User->exists() && $in_hash == $this->User->getActivationHash()) {
// 本登録に有効なURL
// statusフィールドを0に更新
$this->User->saveField( 'status', 0);
$this->Session->setFlash( 'Your account has been activated.');
}else{
// 本登録に無効なURL
$this->Session->setFlash( 'Invalid activation URL');
}
}
再度、ユーザの更新日時をもとにハッシュ値を確認して、有効な場合は'status'を0に更新、無効な場合はエラーメッセージを返します。
本登録(activate)ビュー
<?php
echo $this->Session->flash();
echo $this->Html->link( 'ログイン画面へ', '/users/login');
?>
関連記事
-
-
テーブルからランダムにデータを取り出す(find)
CakePHPでテーブルから特定件数のレコードをランダムに取得するには以下のように指定するとできます。 $this->data = $this->Bulkdata->find( 'all',
-
-
(メール・URL・電話・郵便・IP) データ バリデーション
今回は、プロフィール情報に使用されるデータに絞ったバリデーションルールです。 バリデーションルール 以下の5つのバリデーションルールがコアに用意されています。 email メールアドレス
-
-
Jsヘルパーを使用してAjax更新
更新処理でページ遷移を伴う場合、ページ全体をレスポンスするのに対して、Ajax処理ではページの一部のレスポンスが可能となるためサーバからの通信量を抑えることが可能となります。デモ head
-
-
hasOne アソシエーション
hasOneアソシエーションはテーブル間で1つのレコードに対して他のテーブルに紐付くレコードが1つの場合にjoinする場合に使用します。 CakePHPのドキュメントにならってUserモデルとP
-
-
ログローテーション
CakePHP 2.xではbootstrap.php内にあらかじめアプリケーションログの設定が書かれています。2.xで日付ごとにログファイルが切り替わるよう設定してみました。 日ごとにログを切り替え
-
-
日付・時間のバリデーション
日付や時刻に関するバリデーションは以下のルールがビルトインされています。 date 日付 time 時刻 datetime 日時 (m:「月」を数字表記 / M:「月」を英語表記)
-
-
ネストしたリストを出力「nestedList」
DBやJSONからデータを取得して、そのデータをもとにメニュー表示などネストしたリストを出力させたい場合に「nestedList」が便利です。 ヘルパーに渡すデータは連想配列である必要があります。(
-
-
Syslogログエンジン
2.4から「Syslog」ログクラスが追加され、簡単にSyslogを使用できるようになりました。 CakePHP側の設定はbootstrap.php内のCakeLogコンフィグのengineを'Sy
-
-
FullCalendarを使用してカレンダーアプリケーション
カレンダーアプリケーションを作成するため、カレンダー表示できるプラグインを探索して出会ったFullcalendarを試してみました。シンプルに使用できる上に、オプションがかなり豊富です。ダウンロード
-
-
RSSフィードの取得
コンロトーラ public function getrssfeed() { try { $newsItems = $this->Rss->read( 'http://


Comment
"会員登録"
[…] 参考にしたサイトhttp://kwski.net/cakephp-2-x/1100/ […]
[…] http://kwski.net/cakephp-2-x/1100/ […]
[…] ・CakePHP 2.x – ユーザ登録(仮登録・メール・本登録) ・【CakePHP】モデルでテーブル名を指定する | CakePHP雑記帳 ・CakePHP2.x Formヘルパーコピペ用-ITかあさん ・CakePHP1.2の.ctpファイルでシ […]
[…] CakePHP 2.x – ユーザ登録(仮登録・メール・本登録) http://kwski.net/cakephp-2-x/1100/ […]
cakephp2.X ユーザ登録(仮登録・メール・本登録) http://t.co/nnMccZhTxy
confirmPasswordですが、常にfalseになるため、以下の処理に書き換えましたが何か処理を忘れているのでしょうか
public function confirmPassword( $field, $password, $password_confirm) { if ($this->data[$this->name][$password] == $this->data[$this->name][$password_confirm]) { // パスワードハッシュ化 $this->request->data['User']['password'] = Security::hash( $password, 'sha512', true); return true; } }コメントありがとうございます。
いただいたコードが正しいようです。勝手ながら、修正に上記を使用させていただきます。
ご指摘いただき、ありがとうございました。
“activate”
[…] 参考にしたサイト […]
とても参考になります!ありがとうございます!
1点質問がございます。
signupアクションの5行目にて、
がございますが、私のコントローラーでは都合上、項目ごとに登録する必要がございまして、
としているのですが、上記だとパスワードがnullになります。
かと言って、
とするとハッシュ化されていないパスが登録されてしまいます。
上記の場合どのように指定すれば良いかお教え願えませんでしょうか。
※
本登録(activate)アクションの3行目は、
ですよね??
コメントありがとうございます。
の前にハッシュ化する処理を追加してみて下さい。
(この投稿では、モデル内のconfirmPasswordバリデーションで行っています。)
user_idの件、確かに!ありがとうございました。