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_close:trueにするとブラウザを閉じた時点でセッションが失効encrypt:trueにするとセッションデータを暗号化して保存(暗号鍵は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_onlyをtrueのままにし、JavaScriptからのCookie読み取りを防ぐ- 本番環境では
secureをtrueにし、HTTPS通信でのみCookieを送信する same_siteをlaxまたはstrictに設定し、CSRF対策を補強する- 機密性の高いデータを扱う場合は
encryptをtrueにして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.phpのdriver設定によって変わります。既定ではdatabaseドライバーが使われ、sessionsテーブルに保存されます。fileを選んだ場合はstorage/framework/sessions配下にファイルとして保存されます。
Laravelでセッションの全データを取得するには?
session()->all()、またはSession::all()を使うと、現在のセッションに保存されている全キーを配列で取得できます。
まとめ
Laravelのセッション管理は、config/session.phpの設定とヘルパー関数だけでシンプルに扱える一方、最新バージョンではドライバーの初期値やsessionsテーブルの用意され方が変わるなど、バージョンによる違いも存在します。実際にプロジェクトを作成してsession()->all()やregenerate()などのメソッドを試し、自分のアプリの認証フローに合ったセッション設定・セキュリティ対策を選んでください。

コメント