前回のユーザー登録では、登録後は自動的に認証され、ユーザーはあたかもすでにログインしたような状態となります。
しかし、デフォルトの設定の2時間のアイドルを過ぎると、ログアウトされてしまいます。そうなると必要なのはユーザー認証のためのログイン画面です。
ログイン画面に必要なのは、
app/Http/Controllers/AuthController.php
のコントローラ。前回にはこのコントローラは、登録画面に使われましたが、コントローラ中の以下のトレイトの使用により、
use AuthenticatesAndRegistersUsers
さらに、
そのトレイトの定義で使われているトレイト、
use AuthenticatesUsers
により、ログインが機能します。その定義を見てみましょう。以下のコードは説明のために、ログインスロットルなどの部分を省いています。
namespace Illuminate\Foundation\Auth; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Lang; trait AuthenticatesUsers { use RedirectsUsers; // ログイン画面の表示 public function getLogin() { // app/resources/views/auth/authenticate.blade.phpがあるならそれを使用 if (view()->exists('auth.authenticate')) { return view('auth.authenticate'); } // authenticate.blade.phpがないなら、login.blade.phpを使用 return view('auth.login'); } // ログインボタンを押したら以下を実行 public function postLogin(Request $request) { // 入力バリデーション $this->validate($request, [ $this->loginUsername() => 'required', 'password' => 'required', ]); $credentials = $this->getCredentials($request); if (Auth::attempt($credentials, $request->has('remember'))) { // 認証成功後の処理:リダイレクトとか return $this->handleUserWasAuthenticated($request); } // 認証失敗なら、ログイン画面にエラーを表示 return redirect($this->loginPath()) ->withInput($request->only($this->loginUsername(), 'remember')) ->withErrors([ $this->loginUsername() => $this->getFailedLoginMessage(), ]); } // 認証成功後の処理。目的の画面にリダイレクト protected function handleUserWasAuthenticated(Request $request) { if (method_exists($this, 'authenticated')) { return $this->authenticated($request, Auth::user()); } return redirect()->intended($this->redirectPath()); } // ユーザーのクレデンシャル、つまりemailとpasswordをゲット protected function getCredentials(Request $request) { return $request->only($this->loginUsername(), 'password'); } // ログアウト、つまりクッキーの削除。そしてリダイレクト。デフォルトはルートディレクトリへ public function getLogout() { Auth::logout(); return redirect(property_exists($this, 'redirectAfterLogout') ? $this->redirectAfterLogout : '/'); } ...
postLogin()
では、入力バリデーションの後に、Auth::attempt
が実行されます。そこでは、config/auth.php
で指定したドライバー(Eloquent)を使用して、DBにEメールと暗号化されたパスワードがマッチするかどうかチェックして結果を返します。マッチしたなら、そこでセッションを作成して認証された事実を残します。認証関連のイベントでフックされているコードもそこで実行されます。
その後に実行される、handleUserWasAuthenticated()
では、redirect()->intended()
により、アクセスを試みた初期のURLへリダイレクトします。
例えば、認証以前に、
http://localhost/demo-auth/public/password/edit
へアクセスを試みると、まず認証のためにログイン画面へリダイレクトされて、ログイン成功後には、上のURLへ自動的に移動します。デフォルトでは、$this->redirectPath()
へ移行します。
ログアウトは、ログインのようにボタンとかは必要とせずに、現在ログインしているならログアウトのURLにアクセスするだけで、ログインのセッションを無効とします。get Login()
のAuth::logout()
がその処理を行います。
上記のコントローラで使用されるテンプレート、login.blade.php
には、以下のようなフォームが含まれます。
<form method="POST" action="/auth/login"> {!! csrf_field() !!} <div> Eメール <input type="email" name="email" value="{{ old('email') }}"> </div> <div> パスワード <input type="password" name="password" id="password"> </div> <div> <input type="checkbox" name="remember"> 次回から入力を省略 </div> <div> <button type="submit">ログイン</button> </div> </form>
さて、これでログイン画面は動作しますが、このフォームで使用される「次回から入力を省略」のチェックボックスは何でしょう?
ここがオフでは、ログインのセッションは2時間で時間切れとなり、再度ログインが必要となります。ここをオンとしてログインが成功となると現在の設定では5年間は、ログインなしで認証が必要な画面へのアクセスが可能となります。Laravelではセキュリティを上げるために、ここがオンのときはトークンを作成してDBに保存し、クッキーの値とマッチするかのチェックを行っています。
さて、ユーザーの認証の部分ができたところで、次回は、どうやってLaravelがこの認証の情報をもとにプライベート画面を保護するかを見てみましょう。
メルマガ購読の申し込みはこちらから。