ここではログインしたユーザが自身のパスワードを変更できるようにしよう.
artisan コマンドでコントローラを作成する.app/Http/Controllers/Auth/ 以下に作成したいので,次のようなコマンドを実行する.
[GakuinHana@rin06 laravelUser]$ php artisan make:controller Auth/ChangePasswordController ⏎ Controller created successfully. [GakuinHana@rin06 laravelUser]$
上のコマンドで次のようなファイルが作成された.
app/Http/Controllers/Auth/ChangePasswordController.php
<?php
namespace App\Http\Controllers\Auth;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class ChangePasswordController extends Controller
{
    //
}
パスワード編集のためのページと実際に変更処理を行うページのルートを定義する.
routes/web.php (抜粋)
Route::get('/', function () {
    return view('welcome');
});
Route::get('/auth/verifyemail/{token}', 'Auth\RegisterController@verify');
Auth::routes();
Route::get('/resend', 'Auth\RegisterController@showReSendForm')->name('resend');
Route::post('/resend', 'Auth\RegisterController@reSend');
Route::get('/password/change', 'Auth\ChangePasswordController@edit');
Route::patch('/password/change','Auth\ChangePasswordController@update')->name('password.change');
Route::get('/home', 'HomeController@index')->name('home');
Route::get('/users/{id}', 'UsersController@show');
先頭に use App\User; を忘れずに定義する.また, __construct() でミドルウェアを呼び出すことによって,コントローラのすべての機能を認証必須にしておく.
app/Http/Controllers/Auth/ChangePasswordController.php
<?php
namespace App\Http\Controllers\Auth;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\User;
class ChangePasswordController extends Controller
{
  /**
   * Create a new controller instance.
   *
   * @return void
   */
  public function __construct()
  {
      $this->middleware('auth');
  }
  public function edit()
  {
    return view('auth.passwords.edit')
            ->with('user', \Auth::user());
  }
  public function update(Request $request)
  {
    dd($request);
  }
}
Profile のページにパスワード変更のためのリンクを設置する.
resources/views/users/show.blade.php (抜粋)
  <div class="panel-body">
      @if (session('status'))
          <div class="alert alert-success">
              {{ session('status') }}
          </div>
      @endif
      <dl>
        <dt>id</dt>
        <dd>{{ $user->id }}</dd>
        <dt>name</dt>
        <dd>{{ $user->name }}</dd>
        <dt>email</dt>
        <dd>{{ $user->email }}</dd>
        <dt>login_id</dt>
        <dd>{{ $user->login_id }}</dd>
        <dt>created_at</dt>
        <dd>{{ $user->created_at }}</dd>
      </dl>
      <p><a href="{{ url('/password/change') }}">Change Password</a></p>
  </div>
続いてパスワード変更用のフォームをデザインする.resources/views/auth/passwords/ ディレクトリに edit.blade.php ファイルを作成する.なお,パスワードの入力確認用のコントロールの name には比較対象となるコントロールの name に _confirmation を追加する.これによって,コントローラで validation を記述する際に,confirmed を追加するだけで2つのパスワードが一致しているかどうかを確認できるようになる.
resources/views/auth/passwords/edit.blade.php
@extends('layouts.app')
@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="panel panel-default">
                <div class="panel-heading">Change Password</div>
                <div class="panel-body">
                    {{-- フラッシュメッセージの表示 --}}
                    @if (session('warning'))
                        <div class="alert alert-warning">
                            {{ session('warning') }}
                        </div>
                    @endif
                    @if (session('status'))
                        <div class="alert alert-info">
                            {{ session('status') }}
                        </div>
                    @endif
                    <form class="form-horizontal" method="POST" action="{{ route('password.change') }}">
                        {{ csrf_field() }}
                        {{ method_field('patch') }}
                        <input type="hidden" name="id" value="{{ $user->id }}">
                        <div class="form-group{{ $errors->has('current_password') ? ' has-error' : '' }}">
                            <label for="current_password" class="col-md-4 control-label">Current Password</label>
                            <div class="col-md-6">
                                <input id="current_password" type="password" class="form-control" name="current_password" required>
                                @if ($errors->has('current_password'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('current_password') }}</strong>
                                    </span>
                                @endif
                            </div>
                        </div>
                        <div class="form-group{{ $errors->has('new_password') ? ' has-error' : '' }}">
                            <label for="new_password" class="col-md-4 control-label">New Password</label>
                            <div class="col-md-6">
                                <input id="new_password" type="password" class="form-control" name="new_password" required>
                                @if ($errors->has('new_password'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('new_password') }}</strong>
                                    </span>
                                @endif
                            </div>
                        </div>
                        <div class="form-group{{ $errors->has('new_password_confirmation') ? ' has-error' : '' }}">
                            <label for="new_password-confirm" class="col-md-4 control-label">Confirm Password</label>
                            <div class="col-md-6">
                                <input id="new_password-confirm" type="password" class="form-control" name="new_password_confirmation" required>
                                @if ($errors->has('new_password_confirmation'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('new_password_confirmation') }}</strong>
                                    </span>
                                @endif
                            </div>
                        </div>
                        <div class="form-group">
                            <div class="col-md-6 col-md-offset-4">
                                <button type="submit" class="btn btn-primary">
                                    Change Password
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection
user_a でログインして,現在のパスワード「password」を新しいパスワード「new.Password」に変更する操作を行ってみる.まだ,実際に変更する処理は記述しておらず,フォームに入力されたパスワードが平文で渡されていることだけが確認できた.
 
 
 
変更したいデータを受け取るところまではできたので,実際にパスワードを変更する処理を記述しよう.なお,Laravel ではパスワードをレインボーテーブル形式で保存しているため,bcrypt() で生成されたパスワードのハッシュ化文字列と実際の生パスワードが一致しているかどうかは単なる文字列比較ではできず,password_verify(生パスワード, ハッシュ値) を利用してパスワードのチェックを行う.なお,新しいパスワードの比較は上述の通り,validation のルールに confirmed を追加するだけでできる(25行目を参照).
app/Http/Controllers/Auth/ChangePasswordController.php
<?php
namespace App\Http\Controllers\Auth;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use App\User;
class ChangePasswordController extends Controller
{
  /**
   * Create a new controller instance.
   *
   * @return void
   */
  public function __construct()
  {
      $this->middleware('auth');
  }
  protected function validator(array $data)
  {
      return Validator::make($data, [
          'new_password' => 'required|string|min:6|confirmed',
      ]);
  }
  public function edit()
  {
    return view('auth.passwords.edit')
            ->with('user', \Auth::user());
  }
  public function update(Request $request)
  {
    // ID のチェック
    //(ここでエラーになることは通常では考えられない)
    if ($request->id != \Auth::user()->id) {
      return redirect('/home')
              ->with('warning', '致命的なエラーです');
    }
    $user = \Auth::user();
    // 現在のパスワードを確認
    if (!password_verify($request->current_password, $user->password)) {
      return redirect('/password/change')
              ->with('warning', 'パスワードが違います');
    }
    // Validation(6文字以上あるか,2つが一致しているかなどのチェック)
    $this->validator($request->all())->validate();
    // パスワードを保存
    $user->password = bcrypt($request->new_password);
    $user->save();
    return redirect('/home')
            ->with('status', 'パスワードを変更しました');
  }
}
では,実際にパスワードを変更してみよう.
 
正しく変更できました.
 
現在のパスワードが違った場合は次の画面.
 
新しいパスワード(2つ)が一致しない場合.
 
新しいパスワードが一致するが,短い場合.
