ホームページ  >  記事  >  バックエンド開発  >  PHP セッション原則の分析と使用

PHP セッション原則の分析と使用

巴扎黑
巴扎黑オリジナル
2016-12-05 09:53:391468ブラウズ

以前、Magic Labというブログで「PHPセッション原則の徹底分析」という記事を読んだことがありますが、その著者はセッションの設定と機能の観点から、コードの実行プロセスにおける各リンクと関連パラメータの変更について説明していました。本当は元の記事を再投稿したかったのですが、元のブログが閉鎖されてしまいました。この大規模な再申請によるものなのか、それとも他の理由によるものなのかはわかりません。一部の元の情報は Baidu のスナップショットを通じて見つかりました。見つからなかった情報は、誰もがセッションをよりよく理解できるように、以前の理解に基づいて再編成されます。

ウェッジ: セッションの俗語

セッション、英語では「会話」と訳され、2 人がチャットし、最初の挨拶の文から最後の別れの文まで、これが会話を構成します。 PHP におけるセッションは主に、クライアント ブラウザとサーバー データ交換の間の会話を指します。ブラウザの開始から終了まで、最も単純なセッション サイクルです。コンピューター言語は一般的にどのように会話を実装するのでしょうか?よくある例を挙げます:
サーバーは理髪店のようなもので、クライアントは髪を切りに行くすべての顧客のようなものです。多くの理髪店では、この種のプロモーション方法を採用しており、10 回連続で消費すると、1 つを獲得できます。無料で実行するには、次の 3 つの方法があります。
1. 理容師は、何度かここに来ればすぐにわかります。これは、セッションをサポートするものと呼ばれます。 2. ゲストには会員カードが発行され、お買い物の際には必ずご持参ください。このカードには1回の消費が記録され、もちろん印鑑が必要です。これをセッション実現といいます。欠点は、会員カードや印鑑を完全に偽造できることです。この本では、各ゲストが自分の会員番号に対応しています。各ゲストは、消費するときに自分の会員番号を報告し、大きな台帳に消費回数を記録します。これが、セッションの会員番号の実装です。頭の中にあるのはクライアントに保存されている SESSIONID であり、大きな台帳はサーバーに保存されているセッション データです。2 番目の方法と比較すると、会員番号とパスワードを変更した場合を除き、セキュリティははるかに高くなります。これを失うと、これはクライアントの SESSIONID の偽造と呼ばれます。

http プロトコルはステートレスであるため、PHP は後者の 2 つの方法でのみセッションを実装できます。前者の Cookie にはすでに述べた欠点があり、あまり安全ではないため、重要なセッションはセッションの使用を選択します。セッションは、SESSIONID というパスワードとしても理解できる識別子に依存する必要があります。これは、クライアントに保存される暗号化された文字列で、通常は Cookie に保存されます。クライアントとサーバー間のすべての通信は、最初にこの SESSIONID を介して行われ、その後サーバーは、サーバーに保存されたセッション データを見つけることができます。サーバーで通話を続けます。

php.ini の共通セッション設定

[Server]
session.save_handler = files
デフォルトは file で、必要に応じてセッションをサーバーに保存する方法を定義します。他の方法 (データベースの使用など) で保存するには、この項目を user に設定する必要があります。

session.save_path = "/tmp/"
セッションが保存される一時ファイルの場所を定義します。サーバー側。

session.auto_start = 0
1 に設定すると、各ファイルに session_start() を記述する必要がなく、セッションが自動的に開始されます。

session.gc_probability = 1
session.gc_divisor = 100
session.gc_maxlifetime = 1440
これら 3 つの構成の組み合わせにより、サーバー側セッションのガベージ コレクション メカニズムが構築され、セッション クリーンアップを実行する確率が構成されます。理論的には、サーバーは一定の確率で gc 関数を呼び出してセッションをクリーンアップします。例: 1/100 は、新しいセッションが初期化されるたびに、ガベージ コレクション プログラムが開始される確率は 1% です。クリーニングの基準は session.gc_maxlifetime で定義された時間です。

[Client]
session.use_cookies = 1
クライアント上のセッション ID によって使用される保存方法を 1 に設定すると、同時に要素 $_COOKIE['PHPSESSIONID'] が記録されます。 $_COOKIE 変数に存在します。

session.use_only_cookies = 1
を 1 に設定すると、セッション ID を保存するためにのみ Cookie が使用されることになります。一般に、クライアントは Cookie をサポートするようになったため、URL を介したセッション ID の受け渡しに関連する攻撃を防ぐために、Cookie を 1 に設定することをお勧めします。

session.use_trans_sid = 0
ここで 1 に設定すると、セッション ID が url パラメータを介して渡されることが許可されることを意味します。同様に、0 に設定することをお勧めします。 Referer_check =
この設定は session.use_trans_sid = 1 にあり、有効になります。その目的は、HTTP ヘッダーの「Referer」をチェックして、URL に含まれるセッション ID に指定された文字列が含まれている必要があるかどうかを判断することです。このパラメータを使用しない場合、URL 内のセッション ID は無効とみなされます。したがって、デフォルトは通常は空、つまりチェックなしです。

session.name = PHPSESSID
sessionid の名前、つまり変数名を定義します。

session.hash_function = 0
を介して PHPSESSID の値を表示できます。session_name の暗号化方式を選択します。0 は md5 暗号化を表し、1 は sha1 暗号化を表します。デフォルトは 0 ですが、sha1 方式を使用した暗号化の方が安全であると言われています。

session.hash_bits_per_character = 4
session_name 文字列内の各文字を指定します。格納されている 2 進数はいくつですか? これらの 2 進数はハッシュ関数の結果です。
4ビット: 0-9、a-f
5ビット: 0-9、a-v
6ビット: 0-9、a-z、A-Z、「-」、「,」

url_rewriter.tags = "a=href,area= href,frame=src,input=src,form=,fieldset="
sid(session_id) を含むように書き換える HTML タグを指定します (「session.use_trans_sid」がオンになっている場合のみ有効)。URL リライターは非表示の HTML タグを追加します。 「」には、URL に追加する必要がある追加情報が含まれます。

session.cookie_lifetime = 0
セッション ID を保存する Cookie ファイルのライフサイクル。0 に設定すると、セッションが終了し、ブラウザを強制的に閉じると、セッション ID が自動的に消えます。

session.cookie_path = /
sessionid cookie ファイルの場所を保存します。

session.cookie_domain = /
sessionid cookie のアクセス許可設定に関連します。 Cookie によって許可されるドメイン名。一般的に、Web サイトのすべてのドメイン名が必要です。クライアントの Cookie はすべてのディレクトリでアクセスできるため、詳細を知る必要がある場合は、「/」に設定する必要があります。関連する設定と setcookie() 関数のドメイン パラメーターの使用法を確認できます。

session.bug_compat_42 = 1
session.bug_compat_warn = 1
これら 2 つの設定は、ほぼ放棄されていると言えますが、古いバージョン用です。 PHP の session_register 関数は主に PHP5 の register_global がデフォルトでオフになっているため、PHP5 ではこの設定が廃止され、直接的に close として定義されます。これら 2 つを学ぶ必要はありません。


session_start() session_start() は何をしますか?

php.ini 内のセッションのいくつかの主要なパラメータが次のように構成されているとします。
session.save_handler = files
session.use_cookies = 1
session.name = PHPSESSID
session.save_path = "/tmp/"

以下にパスします。 コード サンプルは、セッション中の session_start の役割を示しています。

プログラム 1:
session_start();
$_SESSION['uname'] = 'monkey';
$_SESSION['ukey'] = 20119999;
?>


プログラム 1 が終了した後実行されると、session_start() は次の 2 つのことを行います:


1. PHPSESSID を保存するための Cookie ファイルを生成します。このファイルの保存場所と保存方法は、異なるブラウザーにも関係します。このステップでは、シリアル化された文字列 (PHPSESSID) が生成され、ブラウザーの Cookie 情報を確認し、関連するプラグインをインストールします。 Firefox の httpfox、Web Developer などはすべて非常に優れたツールです。


2. サーバー上にセッション データを保存するための一時ファイルを生成します。保存場所は「sess_85891d6a81ab13965d349bde29b2306c」のようになります。「sess_」は、これがセッション ファイルであることを意味します。 85891d6a81ab13965d349bde29b2 306c" はこのセッションです。PHPSESSID はクライアントの PHPSESSID 値と同じです。
「sess_85891d6a81ab13965d349bde29b2306c」ファイルをエディタで開くと、「uname|s:6:"monkey";ukey|i:20119999;」のような内容の文字列が表示されます。このファイルに保存されるのは、$_SESSION 変数の特定の内容であり、各変数は「;」で区切られます。


形式は次のとおりです: 変数名 | 変数の型: [長さ] : 値; たとえば、: uname|s:6:"monkey"; は、SESSION 変数 uname の型が文字列であり、値の長さが 6 であることを意味します。値は猿です

それでは、プログラムが session_start() まで実行された時点で、上記の 2 つのことは完了しているでしょうか?この 2 つのことの間では、どちらが先でどちらが最後になりますか?
実験で証明してみましょう。プログラムを少し変更します。

プログラム 2:
session_start();
$_SESSION['uname'] = 'monkey';
$_SESSION['ukey'] = 20119999 ;

sleep(30);
?> まず、クライアントとサーバー上のすべてのセッション データを削除し、プログラム 2 を実行して、クライアント上のセッション ステータスを確認します。検出: プログラムの実行中に、クライアントは PHPSESSID を保存するための Cookie ファイルを作成しませんでしたが、サーバーにはセッションのコンテンツを保存するための一時ファイルがすでにありましたが、30 を超えるとそのファイルにはコンテンツがありませんでした。秒後、クライアントの Cookie ファイルが生成され、その内容がサーバー側のセッション ファイルに追加されます。


一般的なプロセスは次のようになっていると推測できます: プログラムが session_start() に対して実行されると、サーバーは最初に PHPSESSID と対応するセッション ファイルを生成しますが、プログラムが $_SESSION を割り当てるとき、対応する値はセッション ファイルがメモリに保存されていると仮定します。プログラムの実行後、PHPSESSID を保存する Cookie ファイルがクライアント上に生成され、$_SESSION 変数の値がサーバー上のセッション ファイルに書き込まれます。最後の 2 つのステップで誰が最初に進み、誰が最後になるかについては、それを証明する良い方法をまだ考えていません。


さらに詳しく説明するために、クライアントとサーバー上のセッション関連のコンテンツを削除してプログラム 3 を実行し、1 回目と 2 回目の結果を観察します。
$_SESSION[ 'uname'] = 'monkey';
$session_id = session_id();
$content = file_get_contents($sess_file); **'.$_COOKIE['PHPSESSID'] .'***';
echo '
' .$_SESSION['uname'] '* **'. $content.'***';
?>


上記は、sessin_start() の最初の実行メソッド、つまり、最初の session_start() が出現したときに行われる処理です。プログラムのセット、後続の session_start() を見てみましょう:

想定される php.ini 構成: session.cookie_lifetime = 0

プログラム 4:
session_start();
echo $_SESSION['uname'] ;
echo $_SESSION['ukey'];
?>

これで、クライアントには PHPSESSID を保存する cookie ファイルがすでにあり、サーバーにはセッション コンテンツを保存する sess_ ファイルもあります。通常の内容が出力されます。このとき、ブラウザを強制終了してプログラム4を実行するとどうなるでしょうか?



まず、session.cookie_lifetime は 0 に設定されます。これは、クライアント PHPSESSID によって保存される Cookie ファイルの有効期間が 0 であることを意味します。ブラウザが開いている場合、PHPSESSID の値はメモリに保存されます。強制的に閉じられると、PHPSESSID の値は同時に保存されますが、サーバーは session_destroy() を実行しないため、サーバー上のセッション データ ファイルはまだ存在します。ブラウザが実行プログラム 4 を再度開くと、何も出力されていないことがわかります。そのため、その理由は次のとおりです。


session_start () まず、クライアント Cookie 内の PHPSESSID を取得し、それを「sess_」と組み合わせてファイル名を形成します。 、サーバーにアクセスしてファイルを見つけ、ファイルの内容を取り出して、その内容を $_SESSION グローバル変数に入れて使用します。ブラウザが強制的に閉じられて再度開かれると、この時点での session_start() の実行に相当する以前の PHPSESSID が失われ、この PHPSESSID は以前のサーバーの sess_ ファイルと一致することはできません。 . であるため、コンテンツを取得できません。もちろん、サーバーにはこの PHPSESSID に一致するファイルもありますが、そのファイルはまだ空です。

そのため、同じユーザーが 1 台のマシン、または 1 つのブラウザーにのみログインできる仕組みを実現するために、一部のシステムでは、 session.cookie_lifetime が変更されていない場合は、session.cookie_lifetime を比較的大きな値に設定することをお勧めします。いずれにしても、Cookie ファイルが長時間存在する場合は効果がありません。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。