JavaScriptで設定したCookieはLaravelで単純にRequestから取れないので注意


概要

JavaScriptで設定したCookieはLaravelで単純にRequestから取れない。$request->cookie('flag')などするとnullが帰ってきてしまう。

詳細

JavaScriptで以下のように設定したCookie。

Cookie.set('flag', 'true');

LaravelでCookieの中身を見た場合。

Controller.php
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class IndexController extends Controller
{
    public function index(Request $request)
    {
        dd($request->cookie());
    }
}

出力は以下のようになる。

array [▼
  "flag" => null
  ~略~
]

なぜ起こるか

Laravelは自分で設定したCookieについては暗号化している。
なので仮に暗号化していなかった場合には、Cookieを復号しようとして失敗する。失敗するとnullが返る。

該当の処理は以下のところ。
Laravelバージョンはv6.9.0のコード。

対処法

MiddlewareのEncryptCookiesにおいて、暗号化されていないと期待するリストをかけるので追加する。

EncryptCookies.php

use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;

class EncryptCookies extends Middleware
{
    protected $except = [
        'flag'
    ];
}

おまけ

$_COOKIE を取得すれば生のものが取れるよ、という情報もstackoverflowなどでちらほら見られます。
確かに $_COOKIE はPHPの組み込み変数なので、確かに復号の仕組みが入っていないので生のCookieを取得できますが、Laravelを使っているのであればLaravelの仕組みの上に乗ったほうが良さそうです。

参考: https://www.php.net/manual/ja/reserved.variables.cookies.php