ここではログインしたユーザが自身のパスワードを変更できるようにしよう.
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つ)が一致しない場合.
新しいパスワードが一致するが,短い場合.