Configuring Sessions and Save Handlers

This article deals with how to configure session management and fine tune it to your specific needs. This documentation covers save handlers, which store and retrieve session data, and configuring session behavior.

この記事では、セッション管理を構成し、特定のニーズに合わせて微調整する方法について説明します。このドキュメントでは、セッション データを保存および取得する保存ハンドラと、セッション動作の構成について説明します。

Save Handlers

The PHP session workflow has 6 possible operations that may occur. The normal session follows open, read, write and close, with the possibility of destroy and gc (garbage collection which will expire any old sessions: gc is called randomly according to PHP's configuration and if called, it is invoked after the open operation). You can read more about this at php.net/session.customhandler

PHP セッション ワークフローには、発生する可能性のある 6 つの操作があります。通常のセッションは、open、read、write、close に続き、destroy と gc (古いセッションを期限切れにするガベージ コレクション: gc は PHP の構成に従ってランダムに呼び出され、呼び出された場合は、open 操作の後に呼び出されます) の可能性があります。この詳細については、php.net/session.customhandler を参照してください。

Native PHP Save Handlers

So-called native handlers, are save handlers which are either compiled into PHP or provided by PHP extensions, such as PHP-SQLite, PHP-Memcached and so on.

いわゆるネイティブ ハンドラは、PHP にコンパイルされるか、PHP-SQLite、PHP-Memcached などの PHP 拡張機能によって提供される保存ハンドラです。

All native save handlers are internal to PHP and as such, have no public facing API. They must be configured by php.ini directives, usually session.save_path and potentially other driver specific directives. Specific details can be found in the docblock of the setOptions() method of each class. For instance, the one provided by the Memcached extension can be found on php.net.

すべてのネイティブ保存ハンドラーは PHP の内部にあるため、公開 API はありません。これらは、php.ini ディレクティブ (通常は session.save_path および場合によっては他のドライバー固有のディレクティブ) によって構成する必要があります。具体的な詳細は、各クラスの setOptions() メソッドの docblock にあります。たとえば、Memcached 拡張機能によって提供されるものは、php.net で見つけることができます。

While native save handlers can be activated by directly using ini_set('session.save_handler', $name);, Symfony provides a convenient way to activate these in the same way as it does for custom handlers.

ネイティブの保存ハンドラーは ini_set('session.save_handler', $name); を直接使用してアクティブ化できますが、Symfony はカスタム ハンドラーの場合と同じ方法でこれらをアクティブ化する便利な方法を提供します。

Symfony provides drivers for the following native save handler as an example:

symfony は、例として次のネイティブ保存ハンドラーのドライバーを提供します。

Example usage:

使用例:
1
2
3
4
5
6
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeFileSessionHandler;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;

$sessionStorage = new NativeSessionStorage([], new NativeFileSessionHandler());
$session = new Session($sessionStorage);

Note

ノート

With the exception of the files handler which is built into PHP and always available, the availability of the other handlers depends on those PHP extensions being active at runtime.

PHP に組み込まれており、常に使用可能なファイル ハンドラーを除いて、他のハンドラーの可用性は、実行時にアクティブな PHP 拡張機能に依存します。

Note

ノート

Native save handlers provide a quick solution to session storage, however, in complex systems where you need more control, custom save handlers may provide more freedom and flexibility. Symfony provides several implementations which you may further customize as required.

ネイティブの保存ハンドラーは、セッション ストレージの迅速な解決策を提供しますが、より詳細な制御が必要な複雑なシステムでは、カスタムの保存ハンドラーがより多くの自由と柔軟性を提供する場合があります。 symfony は、必要に応じてさらにカスタマイズできるいくつかの実装を提供します。

Custom Save Handlers

Custom handlers are those which completely replace PHP's built-in session save handlers by providing six callback functions which PHP calls internally at various points in the session workflow.

カスタム ハンドラーは、セッション ワークフローのさまざまなポイントで PHP が内部的に呼び出す 6 つのコールバック関数を提供することにより、PHP の組み込みセッション セーブハンドラーを完全に置き換えるハンドラーです。

The Symfony HttpFoundation component provides some by default and these can serve as examples if you wish to write your own.

Symfony HttpFoundation コンポーネントはデフォルトでいくつかを提供します。これらは、独自に記述したい場合の例として役立ちます。

Example usage:

使用例:
1
2
3
4
5
6
7
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;

$pdo = new \PDO(...);
$sessionStorage = new NativeSessionStorage([], new PdoSessionHandler($pdo));
$session = new Session($sessionStorage);

Migrating Between Save Handlers

If your application changes the way sessions are stored, use the MigratingSessionHandler to migrate between old and new save handlers without losing session data.

アプリケーションでセッションの保存方法が変更された場合は、MigratingSessionHandler を使用して、セッション データを失うことなく、古い保存ハンドラと新しい保存ハンドラの間で移行します。

This is the recommended migration workflow:

これは、推奨される移行ワークフローです。
  1. Switch to the migrating handler, with your new handler as the write-only one. The old handler behaves as usual and sessions get written to the new one:

    新しいハンドラーを書き込み専用ハンドラーとして、移行中のハンドラーに切り替えます。古いハンドラーは通常どおり動作し、セッションは新しいハンドラーに書き込まれます。
    1
    $sessionStorage = new MigratingSessionHandler($oldSessionStorage, $newSessionStorage);
  2. After your session gc period, verify that the data in the new handler is correct.
    セッション GC 期間の後、新しいハンドラーのデータが正しいことを確認します。
  3. Update the migrating handler to use the old handler as the write-only one, so the sessions will now be read from the new handler. This step allows easier rollbacks:

    古いハンドラーを書き込み専用ハンドラーとして使用するように移行ハンドラーを更新して、セッションが新しいハンドラーから読み取られるようにします。この手順により、ロールバックが容易になります。
    1
    $sessionStorage = new MigratingSessionHandler($newSessionStorage, $oldSessionStorage);
  4. After verifying that the sessions in your application are working, switch from the migrating handler to the new handler.
    アプリケーションのセッションが機能していることを確認したら、移行中のハンドラーから新しいハンドラーに切り替えます。

Configuring PHP Sessions

The NativeSessionStorage can configure most of the php.ini configuration directives which are documented at php.net/session.configuration.

NativeSessionStorage は、php.net/session.configuration に記載されているほとんどの php.ini 設定ディレクティブを設定できます。

To configure these settings, pass the keys (omitting the initial session. part of the key) as a key-value array to the $options constructor argument. Or set them via the setOptions() method.

これらの設定を構成するには、キー (初期セッションの一部を省略) をキーと値の配列として $options コンストラクター引数に渡します。または、setOptions() メソッドを介して設定します。

For the sake of clarity, some key options are explained in this documentation.

わかりやすくするために、このドキュメントではいくつかの主要なオプションについて説明します。

For security, session tokens are generally recommended to be sent as session cookies. You can configure the lifetime of session cookies by specifying the lifetime (in seconds) using the cookie_lifetime key in the constructor's $options argument in NativeSessionStorage.

セキュリティのため、セッション トークンは通常、セッション Cookie として送信することをお勧めします。

Setting a cookie_lifetime to 0 will cause the cookie to live only as long as the browser remains open. Generally, cookie_lifetime would be set to a relatively large number of days, weeks or months. It is not uncommon to set cookies for a year or more depending on the application.

cookie_lifetime を 0 に設定すると、ブラウザが開いている間だけ Cookie が存続します。通常、cookie_lifetime は、比較的大きな日数、週数、または月数に設定されます。アプリケーションによっては、Cookie を 1 年以上設定することも珍しくありません。

Since session cookies are just a client-side token, they are less important in controlling the fine details of your security settings which ultimately can only be securely controlled from the server side.

セッション Cookie はクライアント側のトークンにすぎないため、最終的にはサーバー側からのみ安全に制御できるセキュリティ設定の詳細を制御する上でそれほど重要ではありません。

Note

ノート

The cookie_lifetime setting is the number of seconds the cookie should live for, it is not a Unix timestamp. The resulting session cookie will be stamped with an expiry time of time() + cookie_lifetime where the time is taken from the server.

cookie_lifetime 設定は、Cookie が存続する秒数であり、Unix タイムスタンプではありません。結果のセッション Cookie には、time() + cookie_lifetime の有効期限がスタンプされます。ここで、時間はサーバーから取得されます。

Configuring Garbage Collection

When a session opens, PHP will call the gc handler randomly according to the probability set by session.gc_probability / session.gc_divisor in php.ini. For example if these were set to 5/100, it would mean a probability of 5%.

セッションが開くと、PHP は php.ini の session.gc_probability / session.gc_divisor で設定された確率に従ってランダムに gc ハンドラーを呼び出します。たとえば、これらが 5/100 に設定されている場合、5% の確率を意味します。

If the garbage collection handler is invoked, PHP will pass the value of session.gc_maxlifetime, meaning that any stored session that was saved more than gc_maxlifetime seconds ago should be deleted. This allows to expire records based on idle time.

ガベージ コレクション ハンドラが呼び出された場合、PHP は値 ofsession.gc_maxlifetime を渡します。これは、gc_maxlifetime 秒以上前に保存された保存済みセッションを削除する必要があることを意味します。これにより、アイドル時間に基づいてレコードを期限切れにすることができます。

However, some operating systems (e.g. Debian) do their own session handling and set the session.gc_probability directive to 0 to stop PHP doing garbage collection. That's why Symfony now overwrites this value to 1.

ただし、一部のオペレーティング システム (Debian など) は、独自のセッション処理を行い、session.gc_probability ディレクティブを 0 に設定して、PHP によるガベージ コレクションを停止します。そのため、Symfony はこの値を 1 に上書きするようになりました。

If you wish to use the original value set in your php.ini, add the following configuration:

php.ini に設定された元の値を使用する場合は、次の構成を追加します。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
# config/packages/framework.yaml
framework:
    session:
        gc_probability: null

You can configure these settings by passing gc_probability, gc_divisor and gc_maxlifetime in an array to the constructor of NativeSessionStorage or to the setOptions() method.

これらの設定を構成するには、配列内の gc_probability、gc_divisor、および gc_maxlifetime を NativeSessionStorage のコンストラクターまたは setOptions() メソッドに渡します。

Session Lifetime

When a new session is created, meaning Symfony issues a new session cookie to the client, the cookie will be stamped with an expiry time. This is calculated by adding the PHP runtime configuration value in session.cookie_lifetime with the current server time.

新しいセッションが作成されると、つまり Symfony が新しいセッション Cookie をクライアントに発行すると、Cookie には有効期限がスタンプされます。これは、PHP ランタイム構成値 insession.cookie_lifetime を現在のサーバー時間に加算することによって計算されます。

Note

ノート

PHP will only issue a cookie once. The client is expected to store that cookie for the entire lifetime. A new cookie will only be issued when the session is destroyed, the browser cookie is deleted, or the session ID is regenerated using the migrate() or invalidate() methods of the Session class.

PHP は Cookie を 1 回だけ発行します。クライアントは、その Cookie を存続期間全体にわたって保存することが期待されます。新しい Cookie が発行されるのは、セッションが破棄されたとき、ブラウザの Cookie が削除されたとき、またはセッション ID が Session クラスの migrate() メソッドまたは invalidate() メソッドを使用して再生成されたときだけです。

The initial cookie lifetime can be set by configuring NativeSessionStorage using the setOptions(['cookie_lifetime' => 1234]) method.

setOptions(['cookie_lifetime' => 1234]) メソッドを使用して NativeSessionStorage を構成することにより、Cookie の初期有効期間を設定できます。

Note

ノート

A cookie lifetime of 0 means the cookie expires when the browser is closed.

Cookie の有効期間が 0 の場合、ブラウザーを閉じると Cookie の有効期限が切れます。

Session Idle Time/Keep Alive

There are often circumstances where you may want to protect, or minimize unauthorized use of a session when a user steps away from their terminal while logged in by destroying the session after a certain period of idle time. For example, it is common for banking applications to log the user out after just 5 to 10 minutes of inactivity. Setting the cookie lifetime here is not appropriate because that can be manipulated by the client, so we must do the expiry on the server side. The easiest way is to implement this via garbage collection which runs reasonably frequently. The cookie_lifetime would be set to a relatively high value, and the garbage collection gc_maxlifetime would be set to destroy sessions at whatever the desired idle period is.

ユーザーがログイン中にターミナルから離れたときに、一定のアイドル時間後にセッションを破棄することで、セッションの不正使用を保護したり最小限に抑えたい場合がよくあります。たとえば、バンキング アプリケーションでは、5 ~ 10 分間操作を行わないとユーザーがログアウトするのが一般的です。ここで Cookie の有効期間を設定することは、クライアントによって操作される可能性があるため適切ではありません。そのため、サーバー側で有効期限を設定する必要があります。最も簡単な方法は、かなり頻繁に実行されるガベージ コレクションを介してこれを実装することです。 cookie_lifetime は比較的高い値に設定され、ガベージ コレクション gc_maxlifetime は、目的のアイドル期間が何であれ、セッションを破棄するように設定されます。

The other option is specifically check if a session has expired after the session is started. The session can be destroyed as required. This method of processing can allow the expiry of sessions to be integrated into the user experience, for example, by displaying a message.

もう 1 つのオプションは、セッションの開始後にセッションの有効期限が切れているかどうかを明確に確認することです。セッションは、必要に応じて破棄できます。この処理方法により、たとえばメッセージを表示することにより、セッションの期限切れをユーザーエクスペリエンスに統合することができます。

Symfony records some basic metadata about each session to give you complete freedom in this area.

symfony は、各セッションに関するいくつかの基本的なメタデータを記録して、この分野での完全な自由を提供します。

Session Cache Limiting

To avoid users seeing stale data, it's common for session-enabled resources to be sent with headers that disable caching. For this purpose PHP Sessions has the sessions.cache_limiter option, which determines which headers, if any, will be sent with the response when the session in started.

ユーザーに古いデータが表示されないようにするために、セッション対応のリソースには、キャッシュを無効にするヘッダーを付けて送信するのが一般的です。この目的のために、PHP セッションには sessions.cache_limiter オプションがあり、セッションが開始されたときに応答とともに送信されるヘッダー (存在する場合) を決定します。

Upon construction, NativeSessionStorage sets this global option to "" (send no headers) in case the developer wishes to use a Response object to manage response headers.

構築時に、NativeSessionStorage はこのグローバル オプションを "" (ヘッダーを送信しない) に設定します。これは、開発者が Response オブジェクトを使用して応答ヘッダーを管理したい場合に備えます。

Caution

注意

If you rely on PHP Sessions to manage HTTP caching, you must manually set the cache_limiter option in NativeSessionStorage to a non-empty value.

PHP セッションに依存して HTTP キャッシュを管理する場合は、NativeSessionStorage の cache_limiter オプションを空でない値に手動で設定する必要があります。

For example, you may set it to PHP's default value during construction:

たとえば、構築中に PHP のデフォルト値に設定できます。

Example usage:

使用例:
1
2
3
4
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;

$options['cache_limiter'] = session_cache_limiter();
$sessionStorage = new NativeSessionStorage($options);

Session Metadata

Sessions are decorated with some basic metadata to enable fine control over the security settings. The session object has a getter for the metadata, getMetadataBag() which exposes an instance of MetadataBag:

セッションは、セキュリティ設定を細かく制御できるように、いくつかの基本的なメタデータで装飾されています。セッション オブジェクトには、MetadataBag のインスタンスを公開するメタデータ getMetadataBag() のゲッターがあります。
1
2
$session->getMetadataBag()->getCreated();
$session->getMetadataBag()->getLastUsed();

Both methods return a Unix timestamp (relative to the server).

どちらのメソッドも、Unix タイムスタンプ (サーバーに相対的) を返します。

This metadata can be used to explicitly expire a session on access, e.g.:

このメタデータを使用して、アクセス時にセッションを明示的に期限切れにすることができます。
1
2
3
4
5
$session->start();
if (time() - $session->getMetadataBag()->getLastUsed() > $maxIdleTime) {
    $session->invalidate();
    throw new SessionExpired(); // redirect to expired session page
}

It is also possible to tell what the cookie_lifetime was set to for a particular cookie by reading the getLifetime() method:

getLifetime() メソッドを読み取ることで、特定の Cookie の cookie_lifetime が何に設定されたかを知ることもできます。
1
$session->getMetadataBag()->getLifetime();

The expiry time of the cookie can be determined by adding the created timestamp and the lifetime.

cookie の有効期限は、createdtimestamp と有効期間を加算することで決定できます。