前回のユーザー登録では、登録後は自動的に認証され、ユーザーはあたかもすでにログインしたような状態となります。
しかし、デフォルトの設定の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がこの認証の情報をもとにプライベート画面を保護するかを見てみましょう。
メルマガ購読の申し込みはこちらから。