Help us understand the problem. What is going on with this article?

Laravelの認証機能をカスタマイズしたい

More than 1 year has passed since last update.

やりたいこと

1.認証条件にemailやpassword以外の条件を加えたい
2.認証後のリダイレクト先を変更したい
3.ログオン記録を残したい
4.トークンミスマッチが起きた時に「TokenMismatchException in VerifyCsrfToken」を回避したい

事前準備

2014_10_12_000000_create_users_table.php
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に以下の一文が追加されます。

routes/web.php
Auth::routes();

以上、準備完了しました。

ログイン対象のカラムの変更

ログインフォームをカスタマイズします。

resources/views/auth/login.blade.php
// 変更前
// <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の編集が必要です。

App\Http\Controllers\Auth\LoginController.php
/**
 * [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パラメータを使うと、マイグレーションを自動的に作成されます。

2014_10_12_000000_create_logs_table.php
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
App\Listeners\LogSuccessfulLogin.php
use App\Models\Logs;

class LogSuccessfulLogin
{
    public function handle(Login $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イベントを追加します。

App\Providers\EventServiceProvider.php
protected $listen = [
    'Illuminate\Auth\Events\Login' => [
        // ログオン記録イベント
        'App\Listeners\LogSuccessfulLogin',
    ],
];

それで、ログオン記録を残すことができると思います。

「TokenMismatchException in VerifyCsrfToken」を回避したい

ログインページは長時間放置すると、セッション有効期限切れて、
「TokenMismatchException in VerifyCsrfToken」がでます。

App\Exceptions\Handler.php
    public function render($request, Exception $exception)
    {
        // トークンミス
        if ($exception instanceof \Illuminate\Session\TokenMismatchException){
            return back()->withErrors([trans('auth.failed')]);
        }

        return parent::render($request, $exception);
    }

そうすると、エラーが発生した時に、ログインページに飛ばします。

最後

間違いなどがございましたら、ご指摘いただけると幸いです。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away