PHP:$_SESSION - 一時的に使用されるデータを $_SESSION 変数に保存することの長所と短所は何ですか

StackOverflow https://stackoverflow.com/questions/77826

  •  09-06-2019
  •  | 
  •  

質問

私が最近より頻繁にやり始めたことの 1 つは、 いくつかのデータを取得しています タスクの開始時に そしてそれを $_SESSION['myDataForTheTask'] に保存します.

これは非常に便利に思えますが、このアプローチを使用した場合のパフォーマンス、セキュリティ リスクなどについては何も知りません。それは、より専門知識のあるプログラマーによって定期的に行われることですか、それともアマチュアが行うことですか?

例えば:

if (!isset($_SESSION['dataentry']))
{
    $query_taskinfo = "SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id=" . mysql_real_escape_string($_GET['wave_id']);
    $result_taskinfo = $db->query($query_taskinfo);
    $row_taskinfo = $result_taskinfo->fetch_row();

        $dataentry = array("pcode" => $row_taskinfo[0], "modules" => $row_taskinfo[1], "data_id" => 0, "wavenum" => $row_taskinfo[2], "prequest" => FALSE, "highlight" => array());

        $_SESSION['dataentry'] = $dataentry;
}
役に立ちましたか?

解決

実際、セッション変数は、訪問者が Web サイトに滞在している間ずっとこれらの変数を利用できるようにする唯一の方法 (そしておそらく最も効率的) の 1 つであり、ユーザーが変数を編集する実際の方法はありません (Web サイトの脆弱性を悪用する以外に)。コード、または PHP インタプリタ内) なので、かなり安全です。

これは、ユーザーが変更できる設定を保存する良い方法です。セッションの開始時にデータベースから設定を 1 回読み取ることができ、そのセッション全体で使用できるため、設定が変更された場合にさらにデータベースを呼び出すだけで済みます。もちろん、コードに示すように、設定がすでに存在するかどうか、またはデータベースから抽出する必要があるかどうかを確認するのは簡単です。

一時変数を安全に保存する他の方法は思いつきません(Cookie は簡単に変更でき、ほとんどの場合これは望ましくありません)。そのため、$_SESSION が最適な方法です。

他のヒント

$_SESSION メカニズムは Cookie を使用しています。

Firefox (およびおそらく新しい IE、私自身は確認していません) の場合、それは次のことを意味します。 セッションは開いているタブ間で共有されます. 。それはデフォルトでは期待できないことです。そしてそれは、セッションが「単一のウィンドウ/ユーザーに固有のもの」ではなくなったことを意味します。

たとえば、サイトにアクセスするために 2 つのタブを開いた場合、最初のタブを使用して root としてログインすると、もう一方のタブで root 権限が得られます。

これは、特に電子メール クライアントやその他のもの (e ショップなど) をコーディングする場合には、非常に不便です。この場合、セッションを手動で管理するか、常に再生成されるキーを URL に導入するか、その他のことを行う必要があります。

私はユーザー向けの情報を保存するために常にセッション変数を使用します。パフォーマンスに問題は見られませんでした。セッション データは Cookie (または PHPSESSID Cookie がオフになっている場合)。これが他の Cookie ベースの認証と比べてセキュリティ上のリスクになるとは思えませんし、おそらく実際のデータをユーザーの Cookie に保存するよりも安全だと思います。

ただし、SQL ステートメントにはセキュリティ上の問題があることをお知らせします。

SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id=".$_GET['wave_id'];

あなたがすべき 決して、決して繰り返しません, 、ユーザーが提供したデータを取得し、最初にサニタイズせずにそれを使用して SQL ステートメントを実行します。引用符で囲んで関数を追加します mysql_real_escape_string(). 。そうすれば、ほとんどの攻撃から身を守ることができます。したがって、あなたの行は次のようになります:

$query_taskinfo = "SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id='".mysql_real_escape_string($_GET['wave_id'])."'";

一時データの保存場所を決定する際には、考慮すべき要素がいくつかあります。セッション ストレージは、単一ユーザーに固有のデータに最適です。デフォルトのファイルベースのセッション ストレージ ハンドラーが非効率的であることがわかった場合は、データベースまたは memcache タイプのバックエンドを使用して、別のものを実装できます。見る session_set_save_handler 詳細については。

ユーザーのセッションに共通のデータを保存するのは悪い習慣だと思います。複数のユーザーが頻繁にアクセスするデータを保存するのに適した場所があり、このデータをセッションに保存することで、このデータを必要とするユーザーごとにデータを複製することになります。この例では、ユーザーのセッションに特に関連付けられていない、この wave データ (wave_id に基づく) に対して、別のタイプのストレージ エンジンをセットアップする可能性があります。そうすることで、データを一度プルダウンすると、複数のユーザーが再度プルすることなくデータにアクセスできる場所にデータが保存されます。

独自のサーバー上で実行している場合、またはサーバー上のファイル/メモリを誰も覗き見ることができない環境で実行している場合、セッション データは安全です。これらはサーバーに保存され、識別 Cookie がクライアントに送信されるだけです。もちろん、問題は、他の人が Cookie を盗んで別人になりすますことができるかどうかです。HTTPS を使用し、URL にセッション ID を含めないようにすることで、これらの問題のほとんどからユーザーを守ることができます。(注意しないと、依然として XSS が Cookie を取得するために使用される可能性があります。 Jeef Atwoods の投稿 あまりにも。)

セッション変数に何を格納するかについては、買い物かごなどの別のページで再度参照したい場合はそこにデータを置きますが、この結果を生成するために使用される単なる一時的なデータの場合はそこに置かないでください。現在表示されている投稿のタグのリストなどのページ。セッションはユーザーごとの永続データ用です。

入力検証を改善するもう 1 つの方法は、_GET['wave_id'] 変数をキャストすることです。

$query_taskinfo = "SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id=".(int)$_GET['wave_id']." LIMIT 1";

wave_id は整数であり、答えは 1 つだけであると仮定しています。

意思

セッションを使用する場合のその他の欠点は次のとおりです。

  1. $_SESSION データの有効期限は次のとおりです session.gc_maxlifetime 数秒間の非アクティブ状態。
  2. 忘れずに電話する必要があります session_start() セッションデータを使用するすべてのスクリプトに対して。
  3. 複数のサーバーにわたる負荷分散によって Web サイトを拡張すると、ユーザーは毎回同じサーバーにリダイレクトされる必要があるため、問題が発生する可能性があります。これを「Sticky Sessions」で解決します。

$_SESSION アイテムはセッションに保存され、デフォルトではディスク上に保存されます。あなたがしたように、独自の配列を作成して「dataentry」配列エントリにそれを詰め込む必要はありません。$_SESSION['pcode']、$_SESSION['modules'] などを使用できます。

先ほど述べたように、セッションはディスクに保存され、セッションへのポインタは Cookie に保存されます。したがって、ユーザーはセッション データを簡単に入手できません。

IMO、セッションに内容を保存することは完全に許容されます。これはデータを永続化するための優れた方法です。また、多くの場合、すべてを Cookie に保存するよりも安全です。以下にいくつかの懸念があります。

  • 誰かがセッションをハイジャックする可能性があるため、ユーザー認証を追跡するためにセッションを使用する場合は注意してください。読む これ 詳細については。
  • データを保持するのは非常に面倒な方法になる可能性があります。後でクエリを実行する必要がないように、セッション内のすべてを単にスローしないでください。
  • セッションにオブジェクトを保存する場合は、次のリクエストでセッションが開始される前にオブジェクトのクラス ファイルを含めるか、自動ローダーを設定しておく必要があります。

Zend Framework には、有効期限とセキュリティ (キャプチャなど) に役立つセッション データ管理用の便利なライブラリがあります。セッションについての有益な説明もあります。見る http://framework.zend.com/manual/en/zend.session.html

セッションは非常に便利だと感じましたが、注意すべき点がいくつかあります。

1) PHP は、サーバー上の他のユーザーがアクセスできる tmp フォルダーまたはその他のディレクトリにセッションを保存する場合があります。セッションが保存されているディレクトリは、php.ini ファイルに移動して変更できます。

2) 非常に厳重なセキュリティを必要とする価値の高いシステムをセットアップしている場合は、セッションに送信する前にデータを暗号化し、使用するために復号化することができます。注記:トラフィックやサーバーの容量によっては、オーバーヘッドが大きくなりすぎる可能性があります。

3)session_destroy(); を見つけました。セッションはすぐには削除されませんが、PHP ガベージ コレクターがセッションをクリーンアップするまで待つ必要があります。ガベージ コレクターが実行される頻度は、php.ini ファイルで変更できます。しかし、まだあまり信頼できるものではないようです、詳細情報 http://www.captain.at/howto-php-sessions.php

これがどの程度 REST に富んでいるか考えてみてはいかがでしょうか?

つまり「」の「ステートレス通信」の段落を参照してください。REST の簡単な紹介"...

「RESTは、その状態がリソース状態になるか、クライアントに維持されるかのいずれかを義務付けています。言い換えれば、サーバーは、単一の要求を超えて通信するクライアントのいずれかについて、何らかの通信状態を保持する必要はありません。」

(またはウィキペディアの他のリンクのいずれか) 休む)

したがって、あなたの場合、「wave_id」は取得するための賢明なリソースですが、本当にSESSIONに保存したいですか?きっと memcached オブジェクトのリソースをキャッシュする解決策はありますか?

私はこのアプローチをよく使っていますが、特に問題はありません。Cookie とは異なり、データはクライアント側に保存されませんが、これは多くの場合大きな間違いです。

ただし、何でもそうですが、特にユーザー入力を $_SESSION 変数に入力し、後でその変数を SQL クエリで使用する場合は、常にユーザー入力をサニタイズするように注意してください。

これは非常に一般的なことであり、セッションは通常、連続的なデータベース ヒットよりも高速になります。また、PHP 開発者はセッション ハイジャックを防ぐために熱心に取り組んでいるため、かなり安全です。

唯一の問題は、何かが変更されたときにセッション エントリを忘れずに再構築する必要があることです。また、セッションの所有者以外のユーザーによってこのキーの更新が必要になるような変更が行われた場合、このセッション キーを更新するようにシステムに通知する簡単な方法はありません。おそらく大したことではないかもしれませんが、注意すべきことです。

$_SESSION は、ユーザーがページをアクティブに閲覧している間に情報をサーバー側に保存する方法であるため、セキュリティ上非常に役立ちます。そのため、実際の PHP ファイルまたはサーバーに悪用される弱点がない限り、ハッキングするのは困難です。非常に優れた実装の 1 つは、ユーザーがログインしていることを確認する変数を保存し、ログインが確認された場合にのみアクションを実行できるようにすることです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top