やりたいこと
1.認証条件にemailやpassword以外の条件を加えたい
2.認証後のリダイレクト先を変更したい
3.ログオン記録を残したい
4.トークンミスマッチが起きた時に「TokenMismatchException in VerifyCsrfToken」を回避したい
事前準備
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->boolean('status')->default(1)->comment('利用状況(0=停止中,1=利用中)');
$table->string('login_id', 50)->unique()->comment('ログイン用ID');
$table->string('name', 50)->comment('お名前');
$table->string('email', 50)->unique()->comment('メールアドレス');
$table->string('password')->comment('パスワード');
$table->rememberToken();
$table->timestamps();
});
マイグレーション実行すると
php artisan migrate
これでユーザテーブルができました。
次、
ログイン画面等はもちろん自分で作ってもいいのですが、今度は自動生成されるものを利用します。
php artisan make:auth
最後、routes/web.phpに以下の一文が追加されます。
Auth::routes();
以上、準備完了しました。
ログイン対象のカラムの変更
ログインフォームをカスタマイズします。
// 変更前
// <input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required autofocus>
// 変更後
<input id="email" type="email" class="form-control" name="username" value="{{ old('username') }}" required autofocus>
Laravelの認証は、デフォルトでemail+passwordで認証を行うようになっていますが、
今度は、email或login_id+password+statusで認証を行いたいです。
そうする場合、LoginControllerの編集が必要です。
/**
* [username 認証カラムの変更]
* @return [type] [description]
*/
public function username()
{
$username = request()->input('username');
$field = filter_var($username, FILTER_VALIDATE_EMAIL) ? 'email' : 'login_id';
// 利用中のみのユーザがログインできるようにします
request()->merge([$field => $username, 'status'=> 1]);
return $field;
}
/**
* [credentials 認証カラムの追加 `status`]
* @param Request $request [description]
* @return [type] [description]
*/
protected function credentials(Request $request)
{
return $request->only($this->username(), 'password', 'status');
}
/**
* [redirectPath 認証後のリダイレクト先の変更]
* @return [type] [description]
*/
public function redirectPath()
{
return '/';
}
ログオン記録を残したい
ログオン記録用のテーブルを作成します。
php artisan make:model Log -m
-m
パラメータを使うと、マイグレーションを自動的に作成されます。
Schema::create('logs', function (Blueprint $table) {
$table->increments('id');
$table->string('login_id', 50)->comment('担当者ID');
$table->string('name', 50)->comment('担当者姓名');
$table->string('ip', 50)->comment('IPアドレス');
$table->string('user_agent')->comment('ユーザーエージェント');
$table->timestamps();
});
“ユーザーログインした時”というイベントを作成します。
php artisan make:listener LogSuccessfulLogin
use App\Models\Logs;
class LogSuccessfulLogin
{
public function handle($event)
{
// usersテーブルのupdated_atカラムのみを更新します
$event->user->touch();
// ログオン記録を残します
$model = new Logs;
$model->login_id = \Auth::user()->login_id;
$model->name = \Auth::user()->name;
$model->ip = request()->ip();
$model->agent = request()->header('User-Agent');
$model->save();
}
}
App\Providersにデフォルトで存在しているEventServiceProviderに、
LogSuccessfulLoginイベントを追加します。
protected $listen = [
'Illuminate\Auth\Events\Login' => [
// ログオン記録イベント
'App\Listeners\LogSuccessfulLogin',
],
];
それで、ログオン記録を残すことができると思います。
「TokenMismatchException in VerifyCsrfToken」を回避したい
ログインページは長時間放置すると、セッション有効期限切れて、
「TokenMismatchException in VerifyCsrfToken」がでます。
public function render($request, Exception $exception)
{
// トークンミス
if ($exception instanceof \Illuminate\Session\TokenMismatchException){
return back()->withErrors([trans('auth.failed')]);
}
return parent::render($request, $exception);
}
そうすると、エラーが発生した時に、ログインページに飛ばします。
最後
間違いなどがございましたら、ご指摘いただけると幸いです。