web-dev-qa-db-ja.com

セッション変数は避けるべきですか?

以前はセッション変数に大きく依存していましたが、最近ではクエリ文字列パラメーターなどを使用して、それらの多くが不要であることがわかりました。

私の同僚はセッション変数の使用を拒否しています。これは現実的な目標であり、実際的な理由でセッション変数を回避する必要がありますか?セッション変数を完全に回避できますか(ログインを許可するセッションCookieを除く)。これにより、設計が改善されますか?

私の同僚がそれらを使用しない理由があるいくつかの理由:

  • セッション変数の型なしの性質
  • 状態が失われるセッションタイムアウト
  • セッション変数のグローバルスコープの性質
  • セッションを失うサーバーの負荷分散(.Net固有?)
  • アプリケーションプール/サーバーの再起動
  • それらは不要です
36
Tjaart

アプリケーションにセッション変数がある場合は、次の点を確認してください。

ブラウザの戻るボタンをクリックすると、変数にどのような値を設定しますか?

答えが「現在の値」である場合、セッション変数が役立つことがあります。例としては、ショッピングカートがあります。履歴をさかのぼると、ショッピングカートから物が削除されることはありません。常に現在の状態です。

答えが「以前の値」の場合は、セッション変数を使用しないでください。私が見た悪い使い方には、ページ間でパラメータを渡すことが含まれます。 [戻る]ボタンをクリックしてページに戻ると、ページは必ずしも正しいパラメーターを取得しません。また、2つのタブを開くと、サイトはどのように動作しますか?

戻るボタンの動作を正しくすることは、決してすべてのことで終わりというわけではありませんが、Webサイトをステートレスなアプリケーションと考えるのに役立ちます。一般に、セッション変数の適切な使用法は、数が少なく、はるかに限られています。

41
Tim

HTTPプロトコルはステートレスです。セッションは、HTTPリクエスト全体でクライアントの状態を保持する方法です。プラットフォームの組み込みセッション処理でそれを行うか、クエリ文字列パラメーターで自分で行うかを選択できます。どちらにしても、多くのタスクではセッションの概念が必要です。

同僚はおそらく特定の実装を嫌い、または意図した目的でセッションを使用していません。 HTTPリクエスト全体で特定のクライアント接続に関する情報を保持する必要がある場合は、何らかの形式のセッション永続性が必要です。

次の問題は実装固有です。

セッション変数の型なしの性質

セッション変数のグローバルスコープの性質

セッションを失うサーバーの負荷分散

アプリケーションプール/サーバーの再起動

たとえば、私は最も頻繁にPHPで作業し、リレーショナルデータベースにセッション情報を格納しています。そのため、セッション変数が入力されています。負荷分散とサーバーの再起動によってセッションの問題が発生することはありません。

これはもっと面白いです:

状態が失われるセッションタイムアウト

ほとんどの場合、セッションはCookieを介して保存されます。これらはクライアントがいつでも削除できます。ただし、クエリ文字列パラメーターを使用して保存することもできるため、クライアントでタイムアウトすることはありません。サーバーのタイムアウトはあなた次第です。したがって、この問題でさえ実装固有です。

特定の実装が気に入らないからといって、セッションの概念全体を捨てないでください。優れたWebアプリケーションフレームワークであれば、セッションを適切に使用して、ユーザーのログインを維持したり、ユーザーの現在の訪問に固有の何かを保持したりできます。ユーザーのデータベースレコードは、ログイン時にユーザー固有の情報を保存するために使用できます(使用する必要があります)。ただし、匿名の訪問者は、最近訪問したページの短いリストや、彼らがすでに見た通知を隠す。一般に、セッションの保存には、一時的な情報だけが適切です。

25
Matt S

他の人は多くの良い点(繰り返しは避けます)を作りましたが、バディのテクニックには、まだ議論されていない1つの側面があります:セキュリティ

コードを見ない限り、どのような脆弱性が発生しているのかを知ることは不可能ですが、ここで頭に浮かぶいくつかのことを考えます。

  • Session fixation:ユーザーにURLに既に必要な情報が含まれているリンクをクリックさせるだけで簡単にできる強力な攻撃(ユーザーに、 Cookieが適切に設定されています)。
  • SQLインジェクション(またはその他の悪意のある入力):ユーザーからのものを信頼しないでください。セッション変数には、サーバーから離れることができないという利点があるため、ユーザーが変数を直接変更することはできません。データをintoセッションに入れる前にサニタイズする必要がありますが、後で取得する値はいつでも信頼できます。すべてがクエリ文字列を介して渡される場合、悪意のある入力を受け入れていないことを確認するために必要な検証がたくさんあります。
  • 改ざんされた入力を使用してデータを破壊する:SQLインジェクションと同様に、どのくらいの量のデータをやり取りしていますか?それはどれほど重要ですか?クエリ文字列の値を変更することで、アプリの動作を変更できますか?値を変更してサーバー上のデータを破壊できますか?サーバー上のデータを破損した場合、他のユーザーに影響しますか? (あなたの答えが「いいえ」だった場合、私の返答は「あなたはよろしいですか?確認する必要のある場所がたくさんあります。」)。

これらはすべて、セッションを使用するときにも発生する可能性がありますが、バディが何をしているかがわからない場合は、かなり簡単になります

14
riwalk

セッション変数は、古いBasicグローバル変数にある程度似ています。負担は、それら、それらの内容、それらの範囲、およびそれらの使用方法を追跡することです。古いバージョンのBASICと同じように。そうは言っても、プログラミングモデル(ASP、MVCなど)の不可欠で非常に重要な部分になるように設計されたメカニズムの使用を完全に無視するのはなぜですか?

セッション変数の使用で私が遭遇した唯一の悪いことは、それらを追跡し続けるためにあなたに負担をかけることであり、それらが関連データで埋められ、それらを処分することを確認してください。

なんらかの方法でプログラミングをしているときにそうするのではないでしょうか。

2
Mac

私は、セッション変数に関連するデバッグの問題があったので、私はあなたの同僚のように思っていました。はい、クエリ文字列、フォームの非表示フィールドなどを使用して、セッション変数がなくてもある程度は対処できます。ただし、アプリケーションに状態を決定するための最も基本的なロジックフロー以外のものがある場合、この方法でこれを行うのは非常に手間がかかります。また、クエリ文字列と非表示フィールドを介してアプリケーションの内部動作を表示するセキュリティリスクもあります。これらはいずれも攻撃ベクトルとして機能する可能性があります。

セッション変数を使用する場合、アプリケーションのロジックフローを決定するため、変数が設定および設定解除されるタイミングを追跡する必要があります。 Cのような言語でのメモリ管理のようなものです。

これは、フレームワークのない比較的小さなプロジェクトでPHPを使用した経験からのものです。他のプラットフォームでは状況が異なる場合がありますが、一般的な原則は依然として適用されると思います。

1
primehunter326

前述のとおり、HTTPはステートレスであり、セッション変数はそれを破ります。ステートレスになるHTTP設計は、リソースのキャッシュに役立ちます。公開されているリソースの場合。

セッション変数なしでウェブサイトをデザインすることは可能ですが、それはより困難です。最も難しい(IMHO)はファンシーなログイン/ログアウトです。HTTP認証スキームは、HTMLフォームを介して認証するために必要なツールを提供しません(JavaScriptで何かをハックするかもしれません https:// untel:passowrd @ mydomain .com )であり、ログアウトしてクロスブラウザ互換にするのはさらに困難です。 w3メーリングリストについていくつかの議論がありましたが、私が正しく覚えていれば、そのアイデアは破棄されました。

残りについては、セッション変数なしで生きられるはずです。データベース、ファイル、またはどこかにいくつかの状態がありますが、Session変数の使用はまれです。

ユーザーがショッピングカートを持っている場合、ユーザーがカートを共有せずに2台のコンピューター/ブラウザーで閲覧できることになっている場合のみ、それは可変セッションになります。

0
Mathieu