PR

【Laravel】他デバイスや他ブラウザで同時ログインをできなくする方法

【Laravel】他デバイスや他ブラウザで同時ログインをできなくする方法 プログラミング
【Laravel】他デバイスや他ブラウザで同時ログインをできなくする方法

前回、Laravelにて『他のデバイス上のセッションを無効化』する方法をご紹介しました。

こちらに関しては、パスワードを変更された場合に他のデバイス上のセッションを無効化するような方法になります。

今回はパスワードの変更は関係なく、単純に他デバイス(例えばPCとSP)や他ブラウザ(例えばChromeとFirefox)で同時ログインできないような方法を紹介したいと思います。

ちなみに本記事で紹介する方法はLaravel5.6~で検証した結果となります。

このブログは現役のエンジニア(プログラマー歴が約12年)の僕(よしたか)が2019年12月後半から日々更新しております。

もしもアフィリエイトは会員登録後も無料です!
今すぐ会員登録してアフィリエイトを始めよう!

Laravelで他デバイスや他ブラウザで同時ログイン不可とは?

他デバイスや他ブラウザで同時ログイン不可とは?これだけではよくわかりませんよね。

例えばですが、

ID: test PW : test

この情報でChromeからtestアカウントにログインしているとします。

Firefoxでもこのtestアカウントにログインした場合、ChromeとFirefox両方で同時ログインができる状態になっています。

こういう時に、『他デバイスや他ブラウザで同時ログイン不可にする』といった機能となります。

Laravelで他デバイスや他ブラウザで同時ログイン不可にする手順

では実際の手順を見ていきましょう。

流れとしては、

  1. ログイン時にログイン時のユーザーエージェントをDBに格納
  2. ログイン中はユーザーエージェントを常にチェック
  3. 1と2のユーザーエージェントをチェックして相違があればログアウト

ログイン時のユーザーエージェント格納カラムの作成

php artisan make:migration add_column_useragent_to_users

このように実行し、作成されたマイグレーションファイルを、

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class AddColumnUseragentToUsers extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->text('useragent')->nullable()->comment('ユーザーエージェント');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn('useragent');
        });
    }
}

このように変更し、

php artisan migrate

マイグレーションの実行。

ユーザーエージェントをチェックするミドルウェアを作成

php artisan make:middleware CheckUserAgent

このように実行し、作成されたミドルウェアファイルを、

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class CheckUserAgent
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $check_useragent1 = $request->header('User-Agent');
        $check_useragent2 = Auth::guard('user')->user()->useragent; // このあたりは環境による
        if($check_useragent1 <> $check_useragent2) {
            Auth::guard('user')->logout();
            return redirect('/');
        }

        return $next($request);
    }
}

このように変更します。

作成したミドルウェアを適用

「app/Http/Kernel.php」の「$routeMiddleware」に追加します。

    protected $routeMiddleware = [
        ・
        ・
        ・
        'check.useragent' => \App\Http\Middleware\CheckUserAgent::class,
    ];

「routes/web.php」の「middleware」に追加します。

Route::group(['middleware' => 'auth'], function() { // このあたりは環境による
↓
Route::group(['middleware' => ['auth', 'check.useragent']], function() { // このあたりは環境による

ログイン時にユーザーエージェントを格納する

「app/Http/Controllers/Auth/LoginController.php」に、

「authenticated」関数がある場合は、save記述のみ追加します。

「authenticated」関数がない場合は、「vendor/laravel/framework/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php」からオーバーライドします。

    protected function authenticated(Request $request, $user)
    {
        $user->useragent = $request->header('User-Agent');
        $user->save();
    }

 

以上で準備ができました。

composer dump-autoload

こちらのコマンドを実行して、試してみましょう。

Chromeでtestアカウントにログインし、その後Firefoxでtestアカウントにログイン、再度Chromeに戻ってF5などで確認すると、Chrome側がログアウトされると思います。(Firefoxはログイン中のまま)

まとめ

この記事のおさらい
  • Laravelで他デバイスや他ブラウザの同時ログインチェックはユーザーエージェントを使うと便利

いかがだったでしょうか。

前回の記事に引き続き、意外とこういった情報ってググっても検索が出てこないものです。少しでも参考になればと思います!

ちなみに、WordpressもLinuxも利用できるレンタルサーバーはエックスサーバーがオススメです。