Web アプリケーションを作成するときに、1 人のユーザーを表す User オブジェクトがあるとします。ユーザーがログインしたことを保存する最良の方法は何だと思いますか?
私が考えた2つの方法は次のとおりです。
- ユーザーデータベースIDをセッション変数に保存しました
- ユーザーオブジェクト全体をセッション変数に保存しました
上記の方法を使用する際のより良い提案、問題はありますか? おそらく、セキュリティの問題やメモリの問題などです。
Web アプリケーションを作成するときに、1 人のユーザーを表す User オブジェクトがあるとします。ユーザーがログインしたことを保存する最良の方法は何だと思いますか?
私が考えた2つの方法は次のとおりです。
上記の方法を使用する際のより良い提案、問題はありますか? おそらく、セキュリティの問題やメモリの問題などです。
オブジェクトではなくIDを保存することをお勧めします。欠点は、そのユーザーの情報を取得するたびにデータベースにアクセスする必要があることです。ただし、ページで 1 ミリ秒もカウントしない限り、パフォーマンスは問題になりません。次の 2 つの利点があります。
ユーザーの情報が何らかの形で変更された場合、セッションに古い情報を保存することはありません。たとえば、ユーザーが管理者によって追加の権限を付与された場合、ユーザーがログアウトしてから再度ログインしなくても、それらの権限をすぐに利用できます。
セッション情報がハード ドライブに保存されている場合は、シリアル化可能なデータのみを保存できます。そのため、ユーザー オブジェクトにデータベース接続、オープン ソケット、ファイル記述子などが含まれている場合、これは適切に保存されず、適切にクリーンアップされない可能性があります。
ほとんどの場合、これらの懸念は問題にはならず、どちらのアプローチでも問題ありません。
セキュリティのために、セッションID(GUIDまたは暗号で安全なRNGのいずれか)を生成し、セッションIDをユーザーIDにマップするだけのテーブルを作成します。次に、セッションIDをCookieに保存し、それをユーザーIDのプロキシとして機能させます。
|Session |UserID |
|--------+-------|
|a1d4e...+ 12345 |
|--------+-------|
|c64b2...+ 23456 |
|--------+-------|
これにより、IDを推測して他のユーザーになりすますことはできません。また、ユーザーのセッションを制限して、ユーザーが頻繁にログインする必要があるようにすることもできます(通常は2週間です)。また、セッションに関する他のデータを保存する場合は、このテーブルに追加するだけです。
セッションにすべてのユーザーの属性 (これはパーミッションにまで拡張されます) を保存すると、ユーザーが再度ログインするまで変更が反映されないことに注意してください。
個人的には、すぐに参照できるように名前と ID を保存し、必要なときに残りをフェッチします。
ほとんどの場合、ID を保存するのがベスト プラクティスです。この重要な理由の 1 つはスケーラビリティです。ユーザー オブジェクト (または ID だけでなく、データベースからの任意のエンティティ) を保存すると、サイトにサービスを提供するサーバーの数を増やすという問題が発生します。詳細については、「シェアード ナッシング アーキテクチャ」でググってください。
使用しているプラットフォームに依存すると思います。ASP.net を使用している場合は、FormsAuthenticationクラスと、ログイン ユーザーの設定を保存するために使用できるすべての組み込み (および拡張可能) 機能を確認することをお勧めします。
ユーザー ID とセッション ID のハッシュ値を保存し、それをデータベースのセッション テーブルで照合します。そうすれば、セッション データのスプーフィングが難しくなります。追加のチェックとして、IP もチェックできますか。
セッション変数に格納されているユーザー ID に依存し、それがそのユーザーであると信頼するかどうかはわかりません。これは、かなり簡単に変更され、別のメンバーとしてアクセスできるためです。
通常、ユーザーをセッションに保存します。ログインするまで変更できないという問題は、変更を行った後にセッション内のオブジェクトを新しいコピーに置き換えることで解決できます。
ユーザー オブジェクトはかなり軽量なので、セッション変数に格納することにしました。それが最も効率的かどうかはわかりませんが、これまでのところ非常にうまく機能しています。