イントロダクションIntroduction
HTTPで駆動するアプリケーションはステートレスであるため、セッションで複数のリクエストにわたりユーザーに関する情報を保存する手段を提供しています。そうしたユーザー情報は、後続のリクエストからアクセスできる永続的な保存/バックエンドに通常配置されます。Since HTTP driven applications are stateless, sessions provide a way to store information about the user across multiple requests. That user information is typically placed in a persistent store / backend that can be accessed from subsequent requests.
Laravelには、表現力豊かで統一されたAPIを介してアクセスできるさまざまなセッションバックエンドを用意しています。Memcached、Redis、データベースなどの一般的なバックエンドをサポートしています。Laravel ships with a variety of session backends that are accessed through an expressive, unified API. Support for popular backends such as Memcached[https://memcached.org], Redis[https://redis.io], and databases is included.
設定Configuration
アプリケーションのセッション設定ファイルは、config/session.php
へ保存します。このファイルで利用可能なオプションを確認してください。Laravelはデフォルトで、database
セッションドライバを使用するように設定しています。Your application's session
configuration file is stored at
config/session.php
. Be sure to review
the options available to you in this file. By
default, Laravel is configured to use the
database
session driver.
セッションdriver
設定オプションは、各リクエストのセッションデータをどこに保存するかを定義します。Laravelには様々なドライバがあります。The session driver
configuration option defines where session data will
be stored for each request. Laravel includes a
variety of drivers:
file
- セッションをstorage/framework/sessions
に保存しますfile
- sessions are stored instorage/framework/sessions
.cookie
- セッションを暗号化され安全なクッキーに保存しますcookie
- sessions are stored in secure, encrypted cookies.database
- セッションをリレーショナルデータベースへ保存しますdatabase
- sessions are stored in a relational database.memcached
/redis
- セッションをこれらの高速なキャッシュベースの保存域へ保存しますmemcached
/redis
- sessions are stored in one of these fast, cache based stores.dynamodb
- セッションをAWS DynamoDBへ保存しますdynamodb
- sessions are stored in AWS DynamoDB.array
- セッションをPHP配列に格納し、永続化しませんarray
- sessions are stored in a PHP array and will not be persisted.
テスト中に使用し、セッションに保存したデータが永続化されるのを防ぎます。[!NOTE]
Note: 配列(array)ドライバは主に
The array driver is primarily used during testing[/docs/{{version}}/testing] and prevents the data stored in the session from being persisted.
ドライバの動作要件Driver Prerequisites
データベースDatabase
database
セッションドライバを使用する場合、セッションデータを格納するデータベーステーブルを用意する必要があります。通常、これはLaravelのデフォルト0001_01_01_000000_create_users_table.php
データベースマイグレーションに含まれていますが、何らかの理由でsessions
テーブルがない場合は、make:session-table
Artisanコマンドを使用してこのマイグレーションを生成してください。When
using the
database
session driver, you will
need to ensure that you have
a database table to contain
the session data. Typically,
this is included in
Laravel's default
0001_01_01_000000_create_users_table.php
database
migration[/docs/{{version}}/migrations];
however, if for any reason
you do not have a
sessions
table,
you may use the
make:session-table
Artisan command to generate
this migration:
php artisan make:session-table
php artisan migrate
RedisRedis
LaravelでRedisセッションを使用する前に、PECLを介してPhpRedis
PHP拡張機能をインストールするか、Composerを介してpredis/predis
パッケージ(〜1.0)をインストールする必要があります。Redisの設定の詳細は、LaravelのRedisドキュメントを参照してください。Before
using Redis sessions with
Laravel, you will need to
either install the PhpRedis
PHP extension via PECL or
install the
predis/predis
package (~1.0) via Composer.
For more information on
configuring Redis, consult
Laravel's Redis
documentation[/docs/{{version}}/redis#configuration].
Note:
SESSION_CONNECTION
環境変数またはsession.php
設定ファイルのconnection
オプションを使用して、セッションの保存に使用する Redis接続を指定できます。[!NOTE]
TheSESSION_CONNECTION
environment variable, or theconnection
option in thesession.php
configuration file, may be used to specify which Redis connection is used for session storage.
セッションの操作Interacting With the Session
データの取得Retrieving Data
Laravelでセッションデータを操作する主な方法は、グローバルなsession
ヘルパとRequest
インスタンスの2つあります。最初に、Request
インスタンスを介してセッションにアクセスする方法を見てみましょう。これはルートクロージャまたはコントローラメソッドでタイプヒントを使い取得できます。コントローラメソッドの依存関係は、Laravelサービスコンテナを介して自動的に依存注入されることに注意してください。There are
two primary ways of working
with session data in
Laravel: the global
session
helper
and via a
Request
instance. First, let's look
at accessing the session via
a Request
instance, which can be
type-hinted on a route
closure or controller
method. Remember, controller
method dependencies are
automatically injected via
the Laravel service
container[/docs/{{version}}/container]:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\View\View;
class UserController extends Controller
{
/**
* 特定のユーザーのプロファイルを表示
*/
public function show(Request $request, string $id): View
{
$value = $request->session()->get('key');
// ...
$user = $this->users->find($id);
return view('user.profile', ['user' => $user]);
}
}
セッションからアイテムを取得するときに、get
メソッドの2番目の引数としてデフォルト値を渡すこともできます。指定したキーがセッションに存在しない場合、このデフォルト値を返します。クロージャをデフォルト値としてget
メソッドに渡すと、リクエストされたキーが存在しない場合にそのクロージャを実行し、その実行結果を返します。When you
retrieve an item from the
session, you may also pass a
default value as the second
argument to the
get
method.
This default value will be
returned if the specified
key does not exist in the
session. If you pass a
closure as the default value
to the get
method and the requested key
does not exist, the closure
will be executed and its
result returned:
$value = $request->session()->get('key', 'default');
$value = $request->session()->get('key', function () {
return 'default';
});
グローバルセッションヘルパThe Global Session Helper
グローバルなsession
PHP関数を使用して、セッション内のデータを取得/保存することもできます。session
ヘルパを文字列引数一つで呼び出すと、そのセッションキーの値を返します。キー/値ペアの配列を使用してヘルパを呼び出すと、それらの値をセッションへ保存します。You may
also use the global
session
PHP
function to retrieve and
store data in the session.
When the
session
helper
is called with a single,
string argument, it will
return the value of that
session key. When the helper
is called with an array of
key / value pairs, those
values will be stored in the
session:
Route::get('/home', function () {
// セッションからデータを取得
$value = session('key');
// デフォルト値の指定
$value = session('key', 'default');
// セッションにデータを保存
session(['key' => 'value']);
});
Note: HTTPリクエストインスタンスを介してセッションを使用する場合と、グローバルな
session
ヘルパを使用する場合の、実践的な違いはほとんどありません。どちらのメソッドも、すべてのテストケースで使用できるassertSessionHas
メソッドを使用し、テスト可能です。[!NOTE]
There is little practical difference between using the session via an HTTP request instance versus using the globalsession
helper. Both methods are testable[/docs/{{version}}/testing] via theassertSessionHas
method which is available in all of your test cases.
全セッションデータの取得Retrieving All Session Data
セッション内のすべてのデータを取得する場合は、all
メソッドを使用します。If you
would like to retrieve all
the data in the session, you
may use the all
method:
$data = $request->session()->all();
セッションデータの部分取得Retrieving a Portion of the Session Data
only
メソッドとexcept
メソッドは、セッションデータのサブセットを取得するために使います。The
only
and
except
methods
may be used to retrieve a
subset of the session
data:
$data = $request->session()->only(['username', 'email']);
$data = $request->session()->except(['username', 'email']);
アイテムのセッション存在判定Determining if an Item Exists in the Session
アイテムがセッションに存在するかを判定するには、has
メソッドを使用します。アイテムが存在し、null
でない場合、has
メソッドはtrue
を返します。To
determine if an item is
present in the session, you
may use the has
method. The has
method returns
true
if the
item is present and is not
null
:
if ($request->session()->has('users')) {
// ...
}
値がnull
でも、そのアイテムがセッションに存在するかを判定する場合には、exists
メソッドを使用します。To
determine if an item is
present in the session, even
if its value is
null
, you may
use the exists
method:
if ($request->session()->exists('users')) {
// ...
}
アイテムがセッションに存在しないことを判定するには、missing
メソッドを使用します。そのアイテムが存在しない場合、missing
メソッドはtrue
を返します。To
determine if an item is not
present in the session, you
may use the
missing
method.
The missing
method returns
true
if the
item is not
present:
if ($request->session()->missing('users')) {
// ...
}
データの保存Storing Data
セッションにデータを保存するには、通常、リクエストインスタンスのput
メソッドまたはsession
グローバルヘルパを使用します。To store
data in the session, you
will typically use the
request instance's
put
method or
the global
session
helper:
// リクエストインスタンス経由
$request->session()->put('key', 'value');
// グローバルな"session"ヘルパ経由
session(['key' => 'value']);
配列セッション値への追加Pushing to Array Session Values
push
メソッドを使用して、配列のセッション値へ新しい値を追加できます。たとえば、user.teams
キーにチーム名の配列が含まれている場合、次のように新しい値を配列に追加できます。The
push
method may
be used to push a new value
onto a session value that is
an array. For example, if
the user.teams
key contains an array of
team names, you may push a
new value onto the array
like so:
$request->session()->push('user.teams', 'developers');
アイテムの取得と削除Retrieving and Deleting an Item
pull
メソッドは、単一のステートメントでセッションからアイテムを取得および削除します。The
pull
method
will retrieve and delete an
item from the session in a
single statement:
$value = $request->session()->pull('key', 'default');
Incrementing and Decrementing Session ValuesIncrementing and Decrementing Session Values
セッションデータが増分や減分をしたい整数の場合は、increment
メソッドとdecrement
メソッドを使えます。If your
session data contains an
integer you wish to
increment or decrement, you
may use the
increment
and
decrement
methods:
$request->session()->increment('count');
$request->session()->increment('count', $incrementBy = 2);
$request->session()->decrement('count');
$request->session()->decrement('count', $decrementBy = 2);
データの一時保存Flash Data
後続のリクエストで使用するために、セッションにアイテムを一時保存したい場合があります。flash
メソッドを使い実現できます。このメソッドを使用してセッションに保存されたデータは、即時および後続のHTTPリクエスト中に利用可能です。後続のHTTPリクエストの後、一時保存したデータを削除します。一時保存データは、主に持続保存の必要がないステータスメッセージに役立ちます。Sometimes
you may wish to store items
in the session for the next
request. You may do so using
the flash
method. Data stored in the
session using this method
will be available
immediately and during the
subsequent HTTP request.
After the subsequent HTTP
request, the flashed data
will be deleted. Flash data
is primarily useful for
short-lived status
messages:
$request->session()->flash('status', 'Task was successful!');
複数のリクエストの間、一時保存データを保持する必要がある場合は、reflash
メソッドを使用します。これにより、後続のリクエストのためすべての一時保存データを保持します。特定の一時保存データのみを保持する必要がある場合は、keep
メソッドを使用します。If you
need to persist your flash
data for several requests,
you may use the
reflash
method,
which will keep all of the
flash data for an additional
request. If you only need to
keep specific flash data,
you may use the
keep
method:
$request->session()->reflash();
$request->session()->keep(['username', 'email']);
一時保存データを現在のリクエストに対してのみ持続するには、now
メソッドを使用します。To
persist your flash data only
for the current request, you
may use the now
method:
$request->session()->now('status', 'Task was successful!');
データの削除Deleting Data
forget
メソッドは、セッションからデータの一部を削除します。セッションからすべてのデータを削除したい場合は、flush
メソッドを使用できます。The
forget
method
will remove a piece of data
from the session. If you
would like to remove all
data from the session, you
may use the
flush
method:
// 一つのキーを削除
$request->session()->forget('name');
// 複数のキーを削除
$request->session()->forget(['name', 'status']);
$request->session()->flush();
セッションIDの再生成Regenerating the Session ID
多くの場合、セッションIDの再生成は、悪意のあるユーザーがアプリケーションに対するセッション固定攻撃を防ぐため行います。Regenerating the session ID is often done in order to prevent malicious users from exploiting a session fixation[https://owasp.org/www-community/attacks/Session_fixation] attack on your application.
LaravelアプリケーションスターターキットまたはLaravel
Fortifyのどちらかを使用している場合、Laravelは認証中にセッションIDを自動的に再生成します。しかし、セッションIDを手作業で再生成する必要がある場合は、regenerate
メソッドを使用できます。Laravel
automatically regenerates
the session ID during
authentication if you are
using one of the Laravel
application starter
kits[/docs/{{version}}/starter-kits]
or Laravel
Fortify[/docs/{{version}}/fortify];
however, if you need to
manually regenerate the
session ID, you may use the
regenerate
method:
$request->session()->regenerate();
セッションIDを再生成してセッションからすべてのデータを一文で削除する必要がある場合は、invalidate
メソッドを使用します。If you
need to regenerate the
session ID and remove all
data from the session in a
single statement, you may
use the
invalidate
method:
$request->session()->invalidate();
セッションブロッキングSession Blocking
アトミックロックをサポートするキャッシュドライバを使用している必要があります。現在、これらのキャッシュドライバには、
Warning! セッションブロッキングを利用するには、アプリケーションでmemcached
、dynamodb
、redis
、database
、file
、array
ドライバをサポートしています。また、cookie
セッションドライバを使用することはできません。[!WARNING]
To utilize session blocking, your application must be using a cache driver that supports atomic locks[/docs/{{version}}/cache#atomic-locks]. Currently, those cache drivers include thememcached
,dynamodb
,redis
,database
,file
, andarray
drivers. In addition, you may not use thecookie
session driver.
デフォルトでは、Laravelは同じセッションを使用するリクエストを同時に実行することを許可します。したがって、たとえば、JavaScript HTTPライブラリを使用してアプリケーションへ2つのHTTPリクエストを作成すると、両方が同時に実行されます。多くのアプリケーションでは、これは問題ではありません。ただし、セッションデータの損失が、両方がセッションへデータを書き込む2つの異なるアプリケーションエンドポイントに同時にリクエストを行うアプリケーションの小さなサブセットで発生する可能性があります。By default, Laravel allows requests using the same session to execute concurrently. So, for example, if you use a JavaScript HTTP library to make two HTTP requests to your application, they will both execute at the same time. For many applications, this is not a problem; however, session data loss can occur in a small subset of applications that make concurrent requests to two different application endpoints which both write data to the session.
これを軽減するために、Laravelは特定のセッションの同時リクエストを制限できる機能を提供します。これを使用するには、block
メソッドをルート定義にチェーンするだけです。この例では、/profile
エンドポイントへの受信リクエストがセッションロックを取得します。このロックが保持されている間、同じセッションIDを共有する/profile
または/order
エンドポイントへの受信リクエストは、実行を続行する前に最初のリクエストの実行が終了するのを待ちます。To
mitigate this, Laravel
provides functionality that
allows you to limit
concurrent requests for a
given session. To get
started, you may simply
chain the block
method onto your route
definition. In this example,
an incoming request to the
/profile
endpoint would acquire a
session lock. While this
lock is being held, any
incoming requests to the
/profile
or
/order
endpoints which share the
same session ID will wait
for the first request to
finish executing before
continuing their
execution:
Route::post('/profile', function () {
// ...
})->block($lockSeconds = 10, $waitSeconds = 10)
Route::post('/order', function () {
// ...
})->block($lockSeconds = 10, $waitSeconds = 10)
block
メソッドは2つのオプションの引数を取ります。block
メソッドの最初の引数は、セッションロックを解放するまでに保持する必要がある最大秒数です。もちろん、この時間より前にリクエストの実行が終了すれば、ロックはより早く解放されます。The
block
method
accepts two optional
arguments. The first
argument accepted by the
block
method is
the maximum number of
seconds the session lock
should be held for before it
is released. Of course, if
the request finishes
executing before this time
the lock will be released
earlier.
block
メソッドの2番目の引数は、セッションロックを取得しようとしているときにリクエストが待機する秒数です。リクエストが指定された秒数以内にセッションロックを取得できない場合、Illuminate\Contracts\Cache\LockTimeoutException
を投げます。The
second argument accepted by
the block
method is the number of
seconds a request should
wait while attempting to
obtain a session lock. An
Illuminate\Contracts\Cache\LockTimeoutException
will be thrown if the
request is unable to obtain
a session lock within the
given number of
seconds.
これらの引数のいずれも渡されない場合、ロックは最大10秒間取得され、リクエストはロックの取得を試行する間、最大10秒間待機します。If neither of these arguments is passed, the lock will be obtained for a maximum of 10 seconds and requests will wait a maximum of 10 seconds while attempting to obtain a lock:
Route::post('/profile', function () {
// ...
})->block()
カスタムセッションドライバの追加Adding Custom Session Drivers
ドライバの実装Implementing the Driver
既存のセッションドライバがアプリケーションのニーズに合わない場合、Laravelでは独自のセッションハンドラが作成できます。カスタムセッションドライバは、PHPの組み込みのSessionHandlerInterface
を実装する必要があります。このインターフェイスには、いくつかの簡単なメソッドが含まれています。スタブ化されたMongoDBの実装は次のようになります。If none
of the existing session
drivers fit your
application's needs, Laravel
makes it possible to write
your own session handler.
Your custom session driver
should implement PHP's
built-in
SessionHandlerInterface
.
This interface contains just
a few simple methods. A
stubbed MongoDB
implementation looks like
the following:
<?php
namespace App\Extensions;
class MongoSessionHandler implements \SessionHandlerInterface
{
public function open($savePath, $sessionName) {}
public function close() {}
public function read($sessionId) {}
public function write($sessionId, $data) {}
public function destroy($sessionId) {}
public function gc($lifetime) {}
}
Note: Laravelには、拡張機能を格納するためのディレクトリはありません。好きな場所に自由に配置できます。この例では、
MongoSessionHandler
を格納するためにExtensions
ディレクトリを作成しました。[!NOTE]
Laravel does not ship with a directory to contain your extensions. You are free to place them anywhere you like. In this example, we have created anExtensions
directory to house theMongoSessionHandler
.
これらのメソッドの目的は簡単には理解しずらいため、各メソッドの機能について簡単に説明します。Since the purpose of these methods is not readily understandable, let's quickly cover what each of the methods do:
open
メソッドは通常、ファイルベースのセッションストアシステムで使用します。Laravelにはfile
セッションドライバが付属しているため、このメソッドに何も入れる必要があることはまれです。このメソッドは空のままにしておくことができます。Theopen
method would typically be used in file based session store systems. Since Laravel ships with afile
session driver, you will rarely need to put anything in this method. You can simply leave this method empty.open
メソッドと同様に、close
メソッドも通常は無視できます。ほとんどのドライバにとって、それは必要ありません。Theclose
method, like theopen
method, can also usually be disregarded. For most drivers, it is not needed.read
メソッドは、指定された$sessionId
に関連付いたセッションデータの文字列バージョンを返す必要があります。Laravelがシリアル化を実行するため、ドライバでセッションデータを取得または保存するときに、シリアル化やその他のエンコードを行う必要はありません。Theread
method should return the string version of the session data associated with the given$sessionId
. There is no need to do any serialization or other encoding when retrieving or storing session data in your driver, as Laravel will perform the serialization for you.write
メソッドは、$sessionId
に関連付いた、指定$data
文字列を、MongoDBや選択した別のストレージシステムなどの永続ストレージシステムに書き込む必要があります。繰り返しになりますが、シリアル化を実行しないでください。Laravelがすでにそれを処理しています。Thewrite
method should write the given$data
string associated with the$sessionId
to some persistent storage system, such as MongoDB or another storage system of your choice. Again, you should not perform any serialization - Laravel will have already handled that for you.destroy
メソッドは、永続ストレージから$sessionId
に関連付いたデータを削除する必要があります。Thedestroy
method should remove the data associated with the$sessionId
from persistent storage.gc
メソッドは、指定$lifetime
(UNIXタイムスタンプ)よりも古いすべてのセッションデータを破棄する必要があります。MemcachedやRedisなどの自己期限切れシステムの場合、このメソッドは空のままにしておくことができます。Thegc
method should destroy all session data that is older than the given$lifetime
, which is a UNIX timestamp. For self-expiring systems like Memcached and Redis, this method may be left empty.
ドライバの登録Registering the Driver
ドライバを実装したら、Laravelへ登録する準備が済みました。Laravelのセッションバックエンドへドライバを追加するには、Session
ファサードが提供するextend
メソッドを使用します。サービスプロバイダのboot
メソッドからextend
メソッドを呼び出す必要があります。これは、既存のApp\Providers\AppServiceProvider
から行うか、もしくはまったく新しいプロバイダを作成することもできます。Once
your
driver
has
been
implemented,
you
are
ready
to
register
it
with
Laravel.
To
add
additional
drivers
to
Laravel's
session
backend,
you
may
use
the
extend
method
provided
by
the
Session
facade[/docs/{{version}}/facades].
You
should
call
the
extend
method
from
the
boot
method
of a
service
provider[/docs/{{version}}/providers].
You
may
do
this
from
the
existing
App\Providers\AppServiceProvider
or
create
an
entirely
new
provider:
<?php
namespace App\Providers;
use App\Extensions\MongoSessionHandler;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\ServiceProvider;
class SessionServiceProvider extends ServiceProvider
{
/**
* 全アプリケーションサービスの登録
*/
public function register(): void
{
// ...
}
/**
* アプリケーションの全サービスの初期起動処理
*/
public function boot(): void
{
Session::extend('mongo', function (Application $app) {
// SessionHandlerInterfaceの実装を返す
return new MongoSessionHandler;
});
}
}
セッションドライバを登録したら、SESSION_DRIVER
環境変数か、アプリケーションのconfig/session.php
設定ファイルで、mongo
ドライバをアプリケーションのセッションドライバとして指定します。Once
the
session
driver
has
been
registered,
you
may
specify
the
mongo
driver
as
your
application's
session
driver
using
the
SESSION_DRIVER
environment
variable
or
within
the
application's
config/session.php
configuration
file.