FuelPHP

FuelPHPで会員管理(アプリ編その3)

更新日:

パスワードの自動再発行

今日は、登録ユーザーが自分のパスワードを忘れたときに新しいパスワードを自動的に再発行するプログラムを作成してみたいと思います。

1. まずログインビューにパスワード再発行用のリンクを作成します。レイアウトも大幅に変更しましたので、全コードを記述します。

app/views/user/login.php

<div class="row">
 <div class="span7 offset2 hero-unit">
 <h2 style="text-align:center"><?php echo Asset::img('winlogo.png');?></h2><br>
 <?php echo Form::open(array('name'=>'login','method'=>'post','class'=>'form-horizontal')); ?>
 <?php echo '<div class="alert-error"><p>'.Session::get_flash('error').'</p></div>'?>
 <div class="control-group">
 <label class="control-label" for="username">ユーザー名</label>
 <div class="controls">
 <?php echo Form::input('username',Input::post('username'));?>
 </div>
 </div>
 <div class="control-group">
 <label class="control-label" for="password">パスワード</label>
 <div class="controls">
 <?php echo Form::password('password');?>
 </div>
 </div>
 <?php echo Form::submit('submit','ログイン',array('class' => 'btn btn-primary btn-large span7'));?>
 <?php echo Form::close();?>
 <?php echo Html::anchor('user/autorepass','パスワードをお忘れですか?');?>
 </div><!--/span7 offset2-->
 </div><!--/row-->

ちょっとWordPressのログイン画面みたいですね。ロゴなどを入れるとがらっと雰囲気が変わります。Twitter Bootstrapのhero-unitクラスを使うと簡単にこのようなレイアウトが完成します。 

2. 自動的に新しいパスワードを作成し、登録メールに新しいパスワードを発行するautorepassアクションを下記のように記述します。

app/classes/controller/user.php

//パスワードの自動再発行
 public function action_autorepass(){
 //POST送信なら
 if(Input::method() == 'POST'){
 //受信データの整理
 $username=Input::post('username');
 $email=Input::post('email');
 //登録ユーザーの有無の確認
 $user_count=Model_User::find()
 ->where('username',$username)->where('email',$email)
 ->count();
 //該当ユーザーがいれば
 if($user_count>0){
 //Authのインスタンス化
 $auth=Auth::instance();
 //新しいパスワードの自動発行
 $repass=$auth->reset_password($username); 
 //送信データの整理
 $data['repass']=$repass;
 $data['username']=$username;
 $data['email']=$email;
 $data['anchor']='user/login/';
 $body=View::forge('user/email/autorepass',$data);
 //Eメールのインスタンス化
 $sendmail=Email::forge();
 //メール情報の設定
 $sendmail->from('nakada@winroad.info','WinRoad徒然草');
 $sendmail->to($email,$username);
 $sendmail->subject('パスワードの再発行');
 $sendmail->html_body($body);
 //メールの送信
 $sendmail->send();
 //再発行手続きページへ移動
 return Model_User::theme('template','user/repass-info');
 //該当ユーザーがいなければ
 }else{
 //エラー表示
 Session::set_flash('error', '該当者がいません。');
 }
 }
 //テーマの表示
 return Model_User::theme('template','user/autorepass');
 }

新しいパスワードを発行するのは、Authをインスタンス化して、reset_password(ユーザー名)メソッドを実行するだけ(14行目から17行目)です。とても簡単ですね。

前回のメール送信は、本文も全てcontroller上で作成しましたが、今回は、body部分を別途ビューファイルとして用意して、そのビューファイルをメール送信するようにしてみました。この方がすっきりすると思います。ですので、メール用に別途新しくemailフォルダを作成しました。今後、メールを送信するときのメール本文はこのフォルダ内に作成することにします。

3. メール本文のHTMLビューファイルを下記のように記述します。

app/views/user/email/autorepass.php

<!DOCTYPE HTML>
<html>
<header>
<meta charset="utf-8">
<title>自動再発行</title>
</header>
<body>
<h2><?php echo $username;?> 様</h2>
<p>パスワード再発行の依頼をお受けいたしましたので、
新しいパスワードを発行いたします。</p>
下記のリンクより新しいパスワードでログインして下さい。</p>
<p>尚、以前のパスワードは既に使えなくなっております。</p>
<p>新しいパスワード:<?php echo $repass;?></p>
<p><?php echo Html::anchor($anchor,'ログイン')?></p>
<p>WinRoad徒然草ユーザーによりパスワードの紛失手続きが取られましたので、
このメールを発行いたしました。
身に覚えが無ければサイトの管理人にご相談下さい。</p>
<p>ありがとうございました。</p>
</body>
</html>

4. パスワード発行申請手続き画面のビューファイルを下記のように作成します。

app/views/user/autorepass.php

<div class="row">
<div class="span7 offset2 hero-unit">
<h2 style="text-align:center"><?php echo Asset::img('winlogo.png');?></h2><br>
<p>パスワードの再発行手続きを行いますので、あなたのお名前とご登録のEメールアドレスを入力して下さい。</p>
<?php echo Form::open(array('name'=>'autorepass','method'=>'post','class'=>'form-horizontal')); ?>
<?php echo '<div class="alert-error"><p>'.Session::get_flash('error').'</p></div>'?>
<div class="control-group">
 <label class="control-label" for="username">あなたのお名前</label>
 <div class="controls">
 <?php echo Form::input('username',Input::post('username'));?>
 </div>
</div>
<div class="control-group">
 <label class="control-label" for="email">メールアドレス</label>
 <div class="controls">
 <?php echo Form::input('email',Input::post('email'));?>
 </div>
</div>
<?php echo Form::submit('submit','再発行手続き',array('class' => 'btn btn-primary btn-large span7'));?>
<?php echo Form::close();?>
</div><!--/span7 offset2-->
</div><!--/row-->

5. 再発行手続き完了後の画面表示用ビューファイルを下記のように作成します。

app/view/user/repass-info.php

<div class="row">
<div class="span7 offset2 hero-unit">
<h1 style="text-align:center"><?php echo Asset::img('winlogo.png');?></h1><br>
<h2 style="text-align:center">パスワード再発行手続き</h2>
<p>ご指定のメールアドレスへ再発行手続のメールを送信いたしました。</p>
<p>お受け取りになりましたメールのリンクから再発行手続きをお願いします。</p>
</div><!--/span7 offset2-->
</div><!--/row-->

6. そして例のごとく、beforeアクションに、ログインしていなくてもアクセスできるように許可アクション(autorepass)を追加します。ログイン無しでアクセスするアクションが増えてきて、毎回、ここに追加するのが面倒な場合、ログイン無しで、アクセスできるコントローラ(例えばguestコントローラ又は、loginコントローラ)を別途作成した方がいいかもしれません。

//beforeアクション
 public function before(){
 parent::before();
 //許可するアクション
 $action=array('login','create','provisional','activate','timeout','autorepass');
 //現状のアクション
 $active=Request::active()->action;
 //ログインしていなくて、許可アクション以外は
 if(!Auth::check() and !in_array($active,$action)){
 //ログインページへ移動
 Response::redirect('user/login');
 }
 }

6. 今日は、自動的にパスワードを再発行するプログラムを作成してみましたが、これは、ユーザー名とEメールアドレスを知っている人に勝手に他人のパスワードの再発行ボタンをクリックされる可能性があります。クリックされても、新しいパスワードは本人のメールアドレスに送信されますので、とりあえず大丈夫だと思いますが、勝手にパスワードを変更される可能性があるのは、ちょっと面倒です。

7. そこで、次回は、自分自身で新しいパスワードを発行するプログラムに挑戦してみたいと思います。本日は、以上です。

-FuelPHP
-

Copyright© WinRoad徒然草 , 2018 All Rights Reserved Powered by AFFINGER5.