2

私は、フロントエンドのWebアプリケーションと電話アプリからのリクエストを処理するASP .Net Core 1.1 Web APIを持っています。このアプリは、不動産業者が不動産の点検を行うためのものです。したがって、システムは、検査、プロパティ、ユーザ、代理店などのエンティティを有する。ユーザ(すなわち、不動産代理人)および不動産は、代理店に属する。したがって、不動産業者は1人以上のユーザーと1つ以上のプロパティを持つことができます。ASP .Net Core Web APIのログインユーザーの状態を維持する

たとえば、不動産業者の誰かが検査したすべての不動産のリストを表示することができます。この場合、彼はウェブ/電話アプリのどこかをクリックし、アプリはHTTP GETリクエストをAPIに送り、プロパティのリストを取得します。 Web APIは、この要求を受け取ると、まずどのユーザーがこれを要求しているかを確認した後、このユーザーがどの代理店に属しているかを確認し、この代理店に属するすべてのプロパティを返します。

[Authorize] 
[HttpGet] 
public async Task<IActionResult> GetProperties() 
{ 
    // Get Auth0 identifier for the user performing the request 
    string nameIdentifier = User.Claims.FirstOrDefault(c => c.Type == System.Security.Claims.ClaimTypes.NameIdentifier)?.Value; 
    // Retrieve this user from the database 
    User user = await _context.User.SingleOrDefaultAsync(u => u.Username == nameIdentifier); 
    // Return a list of properties that belong to the user's agency 
    return Ok(_context.Properties 
     .Where(p.AgencyId == user.AgencyId)); 
} 

今、すべてがGETリクエスト:

[Table("agency")] 
public class Agency 
{ 

    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    [Column("agency_id")] 
    public int? Id { get; set; } 

    [Column("name")] 
    public string Name { get; set; } 
} 

[Table("user")] 
public class User 
{ 

    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    [Column("user_id")] 
    public int? Id { get; set; } 

    [Column("username")] 
    public string Username { get; set; } 

    [Column("agency_id")] 
    public int AgencyId { get; set; } 

    [ForeignKey("AgencyId")] 
    public Agency Agency { get; set; } 
} 

[Table("property")] 
public class Property 
{ 

    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    [Column("property_id")] 
    public int? Id { get; set; } 

    [Column("address")] 
    public string Address { get; set; } 

    [Column("agency_id")] 
    public int AgencyId { get; set; } 

    [ForeignKey("AgencyId")] 
    public Agency Agency { get; set; } 
} 

前述の要求を処理したWeb APIのコントローラのアクションは、次のようになりますので、...これらは私が持っている[単純化]のモデルをしていますAPIには、ログインしたユーザーの代理店に関連するレコードをAPIが返す、このようにフィルタリングされます。ユーザーが検査のリストを要求しても、家主やテナントに関わらず、APIは常にユーザーの代理店に属するレコードのみを返します。

ASPコアはステートレスなので、ユーザーがログインしたときにユーザーオブジェクトをサーバーに保存することができず、メモリ内に各コントローラアクションで呼び出す準備ができています。しかし、私はこの往復のような気がしますが、APIがGETリクエストを受信するたびに、このユーザーが所属する機関を無駄にしていることがわかります。これを行うより良い方法はありますか?私は、ASPとウェブ開発一般にはかなり新しいです。任意のアイデア/ヒント/ポインターを高く評価します。

答えて

2

ASP .Net Coreはステートレスなので、ユーザーがログインしたときにサーバー上にユーザーオブジェクトを保存することができず、メモリ内に各コントローラアクションで呼び出す準備ができました。しかし、私はこの往復のような気がしますが、APIがGETリクエストを受信するたびに、このユーザーが所属する機関を無駄にしていることがわかります。


ウェブへようこそ、ステートレス環境です。あなたは各httpリクエストを処理するためにユーザレコードが必要な場合は、基本的には、いくつかの選択肢があります。

  1. これまでのセッションに
  2. 場所を
  3. 場所あなたが必要とするレコードの一部を要求上のデータベースからそれを取得しますクッキーに必要なレコードの一部

各アプローチには賛否両論があります。

オプション1は、ユーザーレコードの最新の最新情報を提供しますが、追加のデータベース往復を要します。また、複数の異なるレコードがある場合は、リクエストを処理する必要があります。どのように物事を設計するかによって、リクエストごとに複数のデータベースラウンドトリップが発生する可能性があります。

オプション2を使用すると、あなたのAsp.Netコアアプリケーションは、インメモリセッションプロバイダを使用するように設定されています。しかし、欠点は、Webアプリケーションがリサイクルされた場合(IISの背後で実行されている場合はかなり一般的です)、セッションがクリアされることです。セッションがSqlServerのようなデータベースプロバイダを使用するように設定されている場合、データベースからセッションを読み込むごとにリクエストごとにデータベースのラウンドトリップが発生します(ただし、セッションに配置され、情報をコンパイルするために必要なdbラウンドトリップ数)データベースバックアップセッションに情報を配置することの欠点は、要求がすべての要求に対してデータベース往復を強制することです。セッション中に配置されます。また、セッションに格納されているデータのサイズを慎重にしないと(データベースから各要求を照会すると)、かなり高速になります。最終的にはパフォーマンス上の問題につながる「セッションに投げ込む」ことは簡単すぎることもあります。

オプション3は、http要求のヘッダー内の各要求と共に移動するクッキーに必要なデータを格納します。これの欠点は、すべてのファイル要求をわずかに大きく(画像リクエストでさえも)することになり、インターネット経由で情報が透過的に送信されないように、Cookieをhttps要求のみに制限したいことでしょう。このアプローチは、通常、非常に少量のデータに対してのみ使用されます。

この概要は決して網羅的なものではなく、選択された方法の状態(クエリパラメータなど)と追加のセキュリティの考慮事項を追跡する追加の方法があります。主な持ち帰りは、はい、ウェブはステートレスな環境ですが、状態を把握する方法はまだありますが、すべてが長所と短所を持ち、単一の方法は常に最高です。大部分の大規模なWebアプリケーションは、Webアプリケーションのさまざまな側面に対して、利用可能なすべてのアプローチのバリエーションを使用します。

あなたはここにAsp.Netコア・セッションとapplicatin状態についての詳細を読むことができます:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state

+1

は、最も優れた答えロンいただきありがとうございます! – user1900799

関連する問題