Laravel Sessionの使い方完全ガイド|設定・保存・取得からセキュリティ対策まで

Laravel入門

Laravelアプリケーションでログイン状態やフォームの入力エラーを一時的に保持するために欠かせないのが「セッション(Session)」です。この記事では、Laravel Sessionの基本概念からconfig/session.phpの設定項目、実際のデータ保存・取得コード、そしてセキュリティ対策までを、実際にLaravelプロジェクトを構築して動作検証しながら解説します。

Laravelのセッション(Session)とは

そもそも「セッション」とは、Webアプリケーションがユーザーごとの状態を複数のHTTPリクエストにまたがって保持する仕組みのことです。HTTPはリクエストごとに接続が完結する「ステートレス」なプロトコルのため、ログイン状態やカート情報などを覚えておくには、サーバー側かクライアント側のどこかにデータを保存しておく必要があります。Laravelでは、この一時的なユーザーデータの保存・管理をIlluminate\Sessionコンポーネントが担っており、session()ヘルパー関数やSessionファサード経由で簡単に読み書きできます。

セッションの設定ファイル(config/session.php)

セッションの挙動はconfig/session.phpで一括管理します。主な設定項目は次のとおりです。

  • driver:セッションデータの保存先を決めるドライバー。file / cookie / database / memcached / redis / dynamodb / arrayから選択
  • lifetime:セッションの有効期限(分単位)。既定値は120分
  • expire_on_closetrueにするとブラウザを閉じた時点でセッションが失効
  • encrypttrueにするとセッションデータを暗号化して保存(暗号鍵はAPP_KEYを使用)
  • same_site:CSRF対策に関わるCookieのSameSite属性(既定はlax

実機検証:最新のLaravelはセッションドライバーの初期値が変わっている

実際にcomposer create-project laravel/laravelでLaravel 13系のプロジェクトを新規作成して確認したところ、SESSION_DRIVERの初期値はfileではなくdatabaseになっていました。

'driver' => env('SESSION_DRIVER', 'database'),

さらに検証を進めると、通常であればphp artisan session:tableでマイグレーションファイルを生成してからmigrateする必要があるはずのセッション用テーブルが、プロジェクト作成直後の時点ですでにデータベースへ作成されていました。database/migrationsの中身を確認すると、原因はcreate_users_tableマイグレーションの中にsessionsテーブルの作成処理がまとめて含まれていたことです。

Schema::create('sessions', function (Blueprint $table) {
    $table->string('id')->primary();
    $table->foreignId('user_id')->nullable()->index();
    $table->string('ip_address', 45)->nullable();
    $table->text('user_agent')->nullable();
    $table->longText('payload');
    $table->integer('last_activity')->index();
});

そのため、最新のLaravelで新規プロジェクトを作った場合は、databaseドライバーを使うために別途マイグレーションを用意する必要はありません。試しにphp artisan session:tableを実行すると、すでにテーブルが存在するためMigration already existsというエラーになることも確認しました。既存のLaravelアプリを長く運用している場合や、旧バージョンからアップグレードした場合は、sessionsテーブルが存在するかphp artisan migrate:statusで確認しておくと安全です。

セッションドライバーごとの保存場所

「Laravelのセッションはどこに保存されるのか」は検索でもよく聞かれる疑問です。ドライバーごとの保存先は次のとおりです。

ドライバー 保存場所 向いている用途
file storage/framework/sessions配下のファイル 単一サーバーでの小〜中規模運用
database sessionsテーブル(既定のドライバー) 複数台構成やセッション内容をSQLで確認したい場合
redis / memcached Redis・Memcachedサーバー上 アクセス集中時の高速な読み書きが必要な場合
cookie ブラウザ側のCookie サーバー側にストレージを持ちたくない場合(容量制限に注意)
array メモリ上のみ(リクエスト終了で消える) 自動テスト実行時

実際、Laravelのphpunit.xmlには最初から<env name="SESSION_DRIVER" value="array"/>という設定が入っており、テスト実行時はセッションをディスクやDBに書き込まないarrayドライバーに自動的に切り替わります。

セッションへのデータ保存・取得・削除

session()ヘルパー関数、またはSessionファサードを使ってデータを操作します。どちらも同じセッションストアを参照するため、書き方の好みで選んで問題ありません。

データの保存

// ヘルパー関数
session(['name' => 'Wren']);

// 複数キーをまとめて保存することも可能
session(['role' => 'admin', 'lang' => 'ja']);

// Sessionファサード
use Illuminate\Support\Facades\Session;

Session::put('name', 'Wren');

データの取得

$name = session('name'); // 'Wren'

// キーが存在しない場合のデフォルト値も指定できる
$theme = session('theme', 'default-value');

// Sessionファサードでも同様
$name = Session::get('name');

存在確認(has / exists / missing)

実際にリクエストを送って挙動を確認したところ、has()exists()には明確な違いがあります。

session(['nullable' => null]);

session()->has('nullable');    // false(値がnullの場合はhasはfalseを返す)
session()->exists('nullable'); // true(キー自体は存在する)
session()->missing('nullable'); // true(hasの逆)

取得して削除(pull)・削除(forget)・全削除(flush)

// 値を取得すると同時にセッションから削除する
$role = session()->pull('role'); // 'admin'(以降のセッションにroleキーは残らない)

// 特定のキーだけ削除
session()->forget('name');

// セッションデータを全て削除
session()->flush();

フラッシュデータ(一度だけ表示するメッセージ)

フォーム送信後の「更新しました」のような通知メッセージには、次のリクエストでのみ有効な「フラッシュデータ」を使います。

Session::flash('status', 'Profile updated!');

実際に1回目のリクエストでflash()を実行し、2回目のリクエストでsession('status')を取得できること、3回目のリクエストではnullに戻っていることを確認しました。表示するリクエストをもう1回だけ延長したい場合はreflash()keep(['status'])を使います。

セッションIDの再生成とセキュリティ対策

ログイン成功時など、権限が変わるタイミングでセッションIDを再生成しておくと、セッション固定攻撃(Session Fixation)対策になります。

// セッションIDのみ再生成(データは維持)
$request->session()->regenerate();

// セッションIDを再生成し、データは破棄する
$request->session()->invalidate();

実際にregenerate()の前後でセッションIDを比較したところ、確かに別のIDへ切り替わることを確認できました。Laravel標準の認証機能(Auth::login()など)はログイン時に内部で自動的にregenerate()を呼び出しますが、独自の認証ロジックを組む場合は明示的に呼び出す必要があります。

このほか、次のような設定もセキュリティ強化に役立ちます。

  • http_onlytrueのままにし、JavaScriptからのCookie読み取りを防ぐ
  • 本番環境ではsecuretrueにし、HTTPS通信でのみCookieを送信する
  • same_sitelaxまたはstrictに設定し、CSRF対策を補強する
  • 機密性の高いデータを扱う場合はencrypttrueにしてAPP_KEYによる暗号化を有効にする

なお、セッションの暗号化・署名に使われるAPP_KEYを紛失・変更すると、既存のセッションやCookieが復号できなくなり、419エラーの原因になることがあります。APP_KEYの生成方法はphp artisan key:generateの使い方で解説しています。

Laravel Guardとの関係

Laravelの標準認証(webガード)はセッションを使ってログイン状態を保持しています。ログイン中のユーザーを識別する仕組みそのものについてはLaravel Guardの使い方と設定方法で詳しく解説しているので、あわせて確認してください。

よくある質問

Laravelのセッションとは何ですか?

ユーザーごとのログイン状態や入力データなどを、複数のHTTPリクエストにまたがって一時的に保持するための仕組みです。Laravelではsession()ヘルパーやSessionファサードを使って読み書きします。

「Session」とはどういう意味ですか?

英語のSessionは「一続きの活動期間」を意味し、Web開発の文脈では「ユーザーがサイトを訪問してから離れるまでの一連のやり取り」、およびその間の状態を保持する仕組みを指します。

Laravelのセッションはどこに保存されますか?

config/session.phpdriver設定によって変わります。既定ではdatabaseドライバーが使われ、sessionsテーブルに保存されます。fileを選んだ場合はstorage/framework/sessions配下にファイルとして保存されます。

Laravelでセッションの全データを取得するには?

session()->all()、またはSession::all()を使うと、現在のセッションに保存されている全キーを配列で取得できます。

まとめ

Laravelのセッション管理は、config/session.phpの設定とヘルパー関数だけでシンプルに扱える一方、最新バージョンではドライバーの初期値やsessionsテーブルの用意され方が変わるなど、バージョンによる違いも存在します。実際にプロジェクトを作成してsession()->all()regenerate()などのメソッドを試し、自分のアプリの認証フローに合ったセッション設定・セキュリティ対策を選んでください。

レン (Wren)

こんにちは。レンです。

Laravelのコードの森に住んでいる、小さな案内役です。
ルーティングの枝やクラスの影を歩きながら、コードの流れや仕組みを眺めています。

このサイトでは、Laravelの基本から実装のコツまで、開発で役立つポイントを静かに整理しています。
難しいことを増やすのではなく、コードの見通しが少し良くなるヒントを届けるのが役目です。

「この処理はどこに書くのがいいのか」
「Laravelではどう考えると整理できるのか」

そんな疑問に、小さなメモを残すような気持ちで記事を書いています。

コードを書いている途中で迷ったとき、
このサイトが少し立ち止まって整理できる場所になればうれしいです。

レン (Wren)をフォローする

コメント