6

私は Asp.net (MVC ですが、これはあまり重要ではありません) アプリケーションを開発しています。PostAuthenticateRequest でユーザー プリンシパルと ID を変更するカスタム IHttpModule があります。

ユーザーのログイン時に、認証 Cookie に UserID と UserName を保存しています。ビジネス サービス クラス全体で必要な IUser (DAO およびビジネス オブジェクト レイヤーによって実装され、それぞれ独自の追加メンバーを持つ) があります。ユーザーが何かを望む場合、IUser オブジェクト インスタンス (通常はビジネス オブジェクト レイヤーから) を提供する必要があるため、認証チケットから ID を提供するだけでは十分ではありません。

それで、ログインしたユーザーの IUser データを永続化する方法と場所を考えていますか?

  1. DB から毎回フェッチしたくない (認証チケットの UserID データに基づく)
  2. セッションがまだ準備ができていないPostAuthenticateRequest内で作業する必要があるため、セッションに保存できません
  3. すべての機能をカスタム IHttpModule 内にカプセル化したい

私が見る選択肢:

  • キャッシュ
  • クッキー
  • (セッション) - PostAuthenticateRequest から PostAcquireRequestState イベントに移動し、そこでプリンシパル/アイデンティティを変更しますが、これは避けたいと思います

物事を複雑にしているように見えるプロセスは次のとおりです。

  1. ユーザーがログインすると、ユーザー データが DB から取得され、後のリクエストのために何らかの方法で永続化されます
  2. ユーザーがログアウトすると、永続化されたメディアからユーザー データを自動的に削除する必要があります
  3. ユーザーは自分のプロファイルを変更します。ユーザー データは破棄し、DB からの次の要求で再読み込みする必要があります

これらのすべてを HttpModule によって自動的に処理して (可能であれば)、これらをリセットするのを忘れるという開発者のエラーを排除したくありません。

また、ハードコードされた変数/キーを読み書きし、アプリケーションの他の部分でそれらを操作することも望んでいません。これは、技術的負債を示すだけです。

質問

  1. 何を提案しますか?
  2. SO はどのようにリクエスト間でユーザー データを保持しますか?
4

1 に答える 1

4

あなたの要件を考えると、最善の解決策は、Cookie から ID を取得し、それを使用して HTTP キャッシュ (HttpContext.Current.Cache) にインデックスを作成することだと思います。

ユーザーがアクセスする方法を維持したい場合は、キャッシュを「UserCache」オブジェクトでラップします。オブジェクトは HttpModule によって構築され、(それを待つ...) シングルトンとしてキャッシュ自体に保存されるか、さらに良いことに、http キャッシュからプルする必要があるときに構築されます。これは、アクセスする必要がある場所と、HttpContext.Current.Cache が直接利用できるかどうかによって異なります。遅延実装を以下に示します。

繰り返しますが、これはわかりやすくするためのものであり、実際に実装する方法ではありません。

public class UserCache
{
  public IUser GetUser(object userKey)
  {
    return HttpContext.Current.Cache[userKey];
  }

  public void AddUser(object userKey, IUser user)
  {
    /* this could pull the key from the user object as well. */
    HttpContext.Current.Cache.Add(/* add the object with key and a sliding expiration that is slightly greater than session timeout */);
  }

  public void ExpireUser(object userKey)
  {
    HttpContext.Current.Cache.Remove(userKey);
  }

  /* If you don't want to do SQL cache dependency */
  public void UpdateUser(object userKey, IUser user)
  {
    HttpContext.Current.Cache.Insert(/* ... */);
  }
}

デフォルトのキャッシング メカニズム (または、DI が提供するキャッシング メカニズムを使用することで、実装に縛られない方がよい) を使用すると、コメントに記載されているように、キャッシュからユーザーを自動的に削除する有効期限を設定できます。SQL サーバーの更新に依存するようにキャッシュを設定して、更新を処理するか、サービスの一部として手動で更新して変更を保存できます。

デフォルト キャッシュの詳細については、こちらを参照してください。キャッシュの依存関係の詳細については、こちらを参照してください。

HttpModule自体では、EndRequestイベントで魔法をかけてリクエストが認証されているかどうかを確認し、Cookieに基づいてユーザーをログアウトできると思いますが、試したことがないのでうまくいくかどうかはわかりませんそれ。MSDN で 1.1 の時代にさかのぼる WAY のこの記事を見て、解決しようとしている問題のいくつかに答えがあるかどうかを確認してください。

SOアーキテクチャとその方法については、データベースの大部分を常にRAMに保持しているため、必要に応じてロードすると思います(http://highscalability.com/stack-overflow-architecture)。

于 2009-08-12T03:23:09.987 に答える