16.

Laravel Cookie 操作まとめ — 設定 / 取得 / 削除 / SameSite / 暗号化解除

編集
この記事の要点
  • 設定: cookie('name', 'value', $minutes) を作り、response()->cookie(...) でレスポンスに乗せる
  • キューイング: Cookie::queue('name', 'value', $minutes) で次のレスポンスに自動添付(簡単)
  • 取得: $request->cookie('name') または Cookie::get('name')
  • 削除: Cookie::forget('name') または Cookie::queue(Cookie::forget('name'))
  • Laravel は EncryptCookies ミドルウェアで値を自動暗号化。素の値で欲しい場合は $except に追加
  • SameSite / Secure / HttpOnly は config/session.php で制御。Cross-site 用途は SameSite=None; Secure

Cookie の設定

use Illuminate\Support\Facades\Cookie;

// 方法 A: レスポンスに直接付ける
return response('Hello')
    ->cookie('user_id', '123', 60);   // 60 分間

// 引数: name, value, minutes, path, domain, secure, httpOnly, raw, sameSite
return response('Hi')
    ->cookie('locale', 'ja', 60 * 24 * 30, '/', null, true, true, false, 'Lax');

// 方法 B: Cookie::queue() で自動付与(最も手軽)
Cookie::queue('user_id', '123', 60);
Cookie::queue(Cookie::make('theme', 'dark', 60 * 24 * 365));
return view('home');

// 方法 C: Symfony 互換のオブジェクト生成
$cookie = cookie('token', 'abc', 60);
return redirect('/dashboard')->cookie($cookie);

// 永続化 (5 年など長期)
Cookie::queue('ga_id', $id, 60 * 24 * 365 * 5);

// 削除されないクッキー (forever)
Cookie::queue(cookie()->forever('ga_id', $id));

Cookie の取得

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cookie;

Route::get('/me', function (Request $request) {
    // 方法 A: Request 経由
    $id = $request->cookie('user_id');

    // 方法 B: Cookie ファサード
    $id = Cookie::get('user_id');

    // 存在チェック
    if ($request->hasCookie('user_id')) { ... }

    // デフォルト値
    $locale = $request->cookie('locale', 'ja');

    return ['id' => $id];
});

Cookie の削除

// レスポンスに削除指示を乗せる
return response('logout')->withoutCookie('user_id');

// キューに削除を積む
Cookie::queue(Cookie::forget('user_id'));

// パスやドメインを限定する場合は同じ条件で削除
Cookie::queue(Cookie::forget('user_id', '/', '.example.com'));

EncryptCookies ミドルウェアと暗号化

Laravel はデフォルトで 全 Cookie を AES-256-CBC で自動暗号化します。フロントエンド JavaScript で生の値を読みたい Cookie(例: locale や Google アナリティクスの _ga)は $except に登録して暗号化対象から外します。

// app/Http/Middleware/EncryptCookies.php
class EncryptCookies extends Middleware
{
    /**
     * 暗号化しない Cookie 名のリスト
     */
    protected $except = [
        'locale',
        '_ga',
        '_gid',
        'consent',
    ];
}

属性の意味(path / domain / secure / httpOnly / sameSite)

属性意味推奨
path送信対象パス/
domain送信対象ドメインサブドメイン共有なら .example.com
secureHTTPS のみ送信本番では必ず true
httpOnlyJS から読めなくするセッション系は true(XSS 対策)
sameSiteCross-site 送信制御Lax 推奨、Cross-site 必要なら None; Secure

セッション Cookie の設定(config/session.php)

// config/session.php
return [
    'lifetime'       => env('SESSION_LIFETIME', 120),   // 分
    'expire_on_close'=> false,
    'encrypt'        => false,                          // セッション本体は別に保管
    'http_only'      => true,
    'same_site'      => env('SESSION_SAME_SITE', 'lax'),
    'secure'         => env('SESSION_SECURE_COOKIE', null),
    'cookie'         => env('SESSION_COOKIE', 'laravel_session'),
    'domain'         => env('SESSION_DOMAIN', null),
    'path'           => '/',
];

// .env
SESSION_LIFETIME=120
SESSION_SAME_SITE=lax
SESSION_SECURE_COOKIE=true       # 本番のみ
SESSION_DOMAIN=.example.com      # サブドメイン共有

JavaScript から Cookie を読む例

// Laravel 側で暗号化対象から外す
protected $except = ['client_data'];

// Controller でセット
Cookie::queue('client_data', json_encode(['theme' => 'dark']), 60);
// フロント側
function getCookie(name) {
  const m = document.cookie.match('(^|;)\\s*' + name + '\\s*=\\s*([^;]+)');
  return m ? decodeURIComponent(m[2]) : null;
}
const data = JSON.parse(getCookie('client_data'));
console.log(data.theme);

よくあるトラブル

症状原因 / 対処
Cookie が保存されないレスポンスが redirect 以外で先に echo していてヘッダ送出済
JS で読めない(HttpOnly)Laravel デフォルトが HttpOnly。手動で httpOnly を false にする
値が文字列「eyJpdiI6...」になる暗号化されている。$except に追加
Cross-site で送られないSameSite=None + Secure 必須(HTTPS 必須)
サブドメイン間で共有できないdomain を .example.com(先頭ドット)に設定

FAQ

Q: 永続 Cookie(ブラウザ閉じても残る)の作り方
A: cookie()->forever('name', 'value')(5 年)または分単位で大きな値を指定。

Q: なぜ cookie() ヘルパーで設定しただけだと反映されない?
A: cookie() は Cookie オブジェクトを作るだけ。response()->cookie($cookie) でレスポンスに添えるか、Cookie::queue($cookie) で自動添付してください。

Q: GDPR 同意バナー用に「同意するまで Cookie を発行しない」を実現したい
A: Cookie::queue を消し、同意イベント受領後に再リクエストで発行。または同意 Cookie 以外を $except 外し AES 暗号化のままにして必須でないものは発行を控える。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. 基本的なルール
  2. 変数
  3. 演算子
  4. 標準ライブラリ
  5. 外部ライブラリ
  6. 制御構文
  7. リスト(配列)
  8. タプル
  9. セット
  10. 辞書(dict)
  11. クラスとメソッド
  12. 継承の概念と必要性
  13. 継承の構文
  14. コンストラクタ
  15. cookieの値の設定と取得
  16. 例外処理
  17. 例外を文字列で出力する方法
  18. httpリクエスト(curl)をする方法
  19. Responseオブジェクトの中身の確認
  20. 変数が空かどうか判定する方法
  21. タイムゾーンの設定と現在日時の取得と文字列化
  22. シングルクォーテーションとダブルクォーテーションの違い