ホームページ >バックエンド開発 >PHPチュートリアル >PHP セッション原則の分析と適用

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

WBOY
WBOYオリジナル
2016-06-13 13:07:54870ブラウズ

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

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

ウェッジ: セッション言語

セッションとは英語で「会話」と訳され、最初の挨拶から最後の別れまでおしゃべりする二人の会話のことです。 PHP におけるセッションは主に、クライアント ブラウザとサーバー データ交換の間の会話を指します。ブラウザの開始から終了まで、最も単純なセッション サイクルです。コンピューター言語は一般的にどのように会話を実装するのでしょうか?よくある例を挙げると:
サーバー側は理髪店のようなもので、クライアント側は髪を切りに行くすべての顧客のようなものです。多くの理髪店では、10 回連続で購入すると無料で購入できます。これを達成するための 3 つの方法について説明します:
1. 理髪師は記憶力が良いので、何度か来ればすぐにわかります。これはセッションをサポートするプロトコル自体と呼ばれます。 2. 各ゲストには会員カードが発行されます。購入のたびにこのカードを持参し、当然スタンプを押す必要があります。これは Cookie によるセッション実現と呼ばれます。セキュリティは高くありません。会員カードや印鑑は間違いなく偽造できます。 3. 理髪店では、顧客ごとに会員番号や個人情報、さらにはパスワードを対応させて、買い物の際に会員番号を申告し、記録します。大台帳の購入数 - ―これは、ゲストの頭の中にある会員番号がクライアントに保存されているSESSIONIDであり、大台帳がサーバーに保存されているセッションデータです。会員番号とパスワードを紛失した場合、これをクライアントの SESSIONID の偽造といいます。
?
http プロトコルはステートレスであるため、PHP は後者の 2 つの方法でのみセッションを実装できます。前者の Cookie にはすでに述べた欠点があり、あまり安全ではないため、重要なセッションはセッションの使用を選択します。セッションは、SESSIONID というパスワードとしても理解できる識別子に依存する必要があります。これは、クライアントに保存される暗号化された文字列で、通常は Cookie に保存されます。クライアントとサーバー間のすべての通信は、最初にこの SESSIONID を介して行われ、その後サーバーは、サーバーに保存されたセッション データを見つけることができます。サーバーで通話を続けます。



php.ini の共通セッション設定 [サーバー]
session.save_handler = ファイル
デフォルトは file で、セッションをサーバーに保存する方法を定義します。ファイルとは、セッションを一時ファイルに保存することを意味します (データベースの使用など) 他の保存方法をカスタマイズする場合は、この項目を設定する必要があります。ユーザー
?
session.save_path = "/tmp/"
サーバー側でセッションが保存される一時ファイルの場所を定義します。
?
session.auto_start = 0
1 に設定すると、各ファイルに session_start() を記述する必要はなくなり、セッションが自動的に開始されます。
?
session.gc_probability = 1
session.gc_divisor = 100
session.gc_maxlifetime = 1440
これら 3 つの構成を組み合わせることで、サーバー セッションのガベージ コレクション メカニズムが構築され、session.gc_probability と session.gc_divisor がセッション クリーニングを実行する確率を構成します。理論的には、サーバーがクリーニングのために gc 関数を定期的に呼び出す可能性があるということです。クリーニングの確率は次のとおりです: gc_probability/gc_divisor 例: 1/100? は、新しいセッションが初期化されるたびに、ガベージ コレクション プログラムが開始される確率が 1% であることを意味します。 session.gc_maxlifetime による。
?
[クライアント]
session.use_cookies = 1
クライアント上のセッション ID の保存方法を 1 に設定すると、同時に、要素 $_COOKIE[‘PHPSESSIONID’] が $_COOKIE 変数に存在します。 ?
session.use_only_cookies = 1
また、クライアント上の sessionid で使用される保存方法も定義します。これを 1 に設定すると、セッション ID の保存に Cookie のみが使用されることになります。一般に、クライアントは Cookie をサポートするようになったため、URL を介したセッション ID の受け渡しに関連する攻撃を防ぐために、Cookie を 1 に設定することをお勧めします。
?
session.use_trans_sid = 0
上記の設定に対応して、ここで 1 に設定されている場合は、url パラメーターを介してセッション ID を渡すことが許可されていることを意味します。同様に、
に設定することをお勧めします。 ?
session.referer_check =? この設定は、session.use_trans_sid = 1 の場合にのみ有効になります。目的は、HTTP ヘッダーの「Referer」をチェックして、URL に含まれるセッション ID にこのパラメーターで指定された文字列が含まれている必要があるかどうかを判断することです。セッション ID は無効とみなされます。したがって、デフォルトは通常空、つまりチェックなしです。?
?
session.name = PHPSESSID
sessionid の名前、つまり変数名を定義します。PHPSESSID の値はブラウザの http ツールで表示できます。 ?
session.hash_function = 0
session_name の暗号化方式を選択します。0 は md5 暗号化を表し、1 は sha1 暗号化を表します。デフォルトは 0 ですが、sha1 暗号化方式を使用する方が安全であると言われています。
?
session.hash_bits_per_character = 4
session_name 文字列の各文字に格納される 2 進数の数を指定します。これらの 2 進数は、ハッシュ関数の結果です。
4?? ビット:?? a-f? 5?? ビット:?? 6?? ビット:?? a-z、?? 「-」、?? 「」 ?
url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=,fieldset="
sid (session_id) を含めるように書き換える HTML タグを指定します (「session.use_trans_sid」がオンになっている場合のみ有効)。URL リライターは、追加情報を含む非表示の「」を追加します。 URL。 ?
?
session.cookie_lifetime = 0
セッション ID を保存する Cookie ファイルのライフサイクル。0 に設定するとセッションが終了し、ブラウザを強制的に閉じる一般的な方法では最後のセッション ID が失われます。 ?
session.cookie_path = /
クライアント上のセッション ID を保存する Cookie ファイルの場所
?
session.cookie_domain = /
sessionid を保存する cookie のドメイン名の設定は、cookie によって許可されるドメイン名のアクセス許可設定に関連します。一般的に、Web サイトのすべてのディレクトリがクライアントの cookie にアクセスできるようにする場合は、次の設定を行う必要があります。さらに詳しく知りたい場合は、setcookie() 関数のドメインパラメータの設定と使用法を参照してください。 ?
session.bug_compat_42 = 1
session.bug_compat_warn = 1
これら 2 つの設定は、ほぼ廃止されたと言えますが、主に session_register 関数用の古いバージョンの PHP を提供するためのものです。PHP5 の register_global はデフォルトでオフになっているため、PHP5 と PHP6 では session_register 関数はまったく使用されません。この設定を廃止し、closed として直接定義するため、これら 2 つを学習する必要はありません。




session_start() は何をするのか?



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

?

以下では、コード例を使用して、セッション中の session_start の役割を説明します。

プログラム 1:

session_start();

$_SESSION['uname'] = '猿';

$_SESSION['ukey'] = 20119999;
?>


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


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


2. サーバー上にセッション データを保存するための一時ファイルを生成します。保存場所は「sess_85891d6a81ab13965d349bde29b2306c」のようになります。これは、これがセッション ファイルであることを意味します。このセッション ID の PHPSESS。クライアントの PHPSESSID 値と同じです。

「sess_85891d6a81ab13965d349bde29b2306c」ファイルをエディタで開くと、「uname|s:6:"monkey";ukey|i:20119999;」のような内容の文字列が表示されます。このファイルに保存されるのは、$_SESSION 変数の特定の内容であり、各変数は「;」で区切られます。


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


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

プログラム 2:
セッション開始();
$_SESSION['uname'] = '猿';
$_SESSION['ukey'] = 20119999;? ?
睡眠(30); ?>?

まず、クライアントとサーバー上のすべてのセッション データを削除してから、プログラム 2 を実行します。プログラムが 30 秒間スリープしている間に、クライアントとサーバーのセッション ステータスを確認します。プログラムの実行中に、クライアントが動作していることがわかります。 PHPSESSID の Cookie ファイルを保存しますが、サーバーにはセッションのコンテンツを保存するための一時ファイルがすでにありますが、30 秒後にはクライアントの Cookie ファイルが生成され、サーバーのセッション ファイルが作成されます。コンテンツが含まれます。


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

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

上記は最初の session_start() の実行方法、つまり、最初の session_start() がプログラムのセットに現れたときに何が行われるかを、後続の session_start() を見てみましょう:

仮想の php.ini 設定: session.cookie_lifetime = 0???????

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

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

?

まず、session.cookie_lifetime が 0 に設定されます。これは、PHPSESSID を使用してクライアントによって保存された Cookie ファイルの有効期間が 0 であることを意味します。ブラウザが開いている場合、PHPSESSID の値はメモリに保存されます。が強制的に閉じられると、PHPSESSID を持つ Cookie が同時に保存されますが、サーバーは 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 までご連絡ください。