Laravel8 セッションの複数タブ対応

セッションはブラウザのインスタンスごとに管理されるため、1つのブラウザ内で複数のタブが開かれた場合は全てのタブで同じセッションが参照されてしまう。
もちろんこの仕様によるメリットもあるが、今回はタブごとにセッションを分けて管理したい場合の方法となります。

やり方は、タブごとにランダムなトークン(文字列)を発行して、そのランダムな文字列の下にタブごとのセッション値を配列で保存します。

トークンの発行

タブを新規で開いた時などにアクセスされるスタートページにトークン発行処理を記述する。

class Page1Controller extends UserController
{
    public function page1(Request $request)
    {
        // ランダム文字列作成
        $token = Str::random(16);

        return view('page1.page1',
            compact(
                'token',
            )
        );
    }
}

bladeにhiddenでトークンを保持

タブごとのトークンは常に持ち回す必要があります。

<form action="{{ route('page2.page2') }}" method="post">
    @csrf
    <div>{{ $token }}</div>
    <input type="hidden" name="token" value="{{ $token }}">
    <input type="text" name="xxx" value="{{ $xxx ?? '' }}">
    <input type="text" name="yyy" value="{{ $yyy ?? '' }}">
    <input type="text" name="zzz" value="{{ $zzz ?? '' }}">
    <button>push</button>
</form>

トークン配下にセッションを保存

トークンをキーとしてセッションを保存します。

class Page2Controller extends UserController
{
    public function page2(Request $request)
    {
        $token = $request->input('token');
        $xxx = $request->input('xxx');
        $yyy = $request->input('yyy');
        $zzz = $request->input('zzz');

        $request->session()->put($token, [
            'xxx' => $xxx,
            'yyy' => $yyy,
            'zzz' => $zzz,
        ]);

        return view('page2',
            compact(
                'token',
                'xxx',
                'yyy',
                'zzz',
            )
        );
    }
}

セッションの抽出

トークンをキーとして該当タブのセッションを抽出します。

class Page3Controller extends UserController
{
    public function page3(Request $request)
    {
        $token = $request->input('token');

        $session = $request->session()->get($token);
        $xxx = $session['xxx'] ?? null;
        $yyy = $session['yyy'] ?? null;
        $zzz = $session['zzz'] ?? null;

        return view('page3.page3',
            compact(
                'token',
                'xxx',
                'yyy',
                'zzz',
            )
        );
    }
}

返信を残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です