Laravel入門トップページ


目次

  1. Composerのダウンロードとインストール
  2. コメント掲示板を作成してみよう
  3. リレーションシップを使いこなそう
  4. ユーザ認証の機能を実現しよう
    1. 概要と準備
    2. メールの設定
    3. 認証機能の実装
    4. 学籍番号の登録とログイン名
    5. 登録メールアドレスの認証
    6. パスワードのリセット
    7. プロフィールの表示
    8. パスワードの変更
  5. マルチ認証の機能を実現しよう
  6. MongoDB に接続しよう
  7. キューを利用しよう
  8. コマンド(コンソール)を利用しよう
  9. 本番環境にデプロイしよう

ユーザ認証の機能を実現しよう

パスワードの変更

ここではログインしたユーザが自身のパスワードを変更できるようにしよう.

目次に戻る

コントローラの作成

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」に変更する操作を行ってみる.まだ,実際に変更する処理は記述しておらず,フォームに入力されたパスワードが平文で渡されていることだけが確認できた.

change_pass-4 change_pass-5 change_pass-6

目次に戻る

パスワード変更の処理を記述

変更したいデータを受け取るところまではできたので,実際にパスワードを変更する処理を記述しよう.なお,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', 'パスワードを変更しました');
  }
}

目次に戻る

実際に変更のテストをしてみる

では,実際にパスワードを変更してみよう.

change_pass-7

正しく変更できました.

change_pass-8

現在のパスワードが違った場合は次の画面.

change_pass-9

新しいパスワード(2つ)が一致しない場合.

change_pass-10

新しいパスワードが一致するが,短い場合.

change_pass-11

目次に戻る