9

Jon Skeet との以前の議論に基づいて作成しています。

私のシナリオの要点は次のとおりです。

  • クライアント アプリケーションには、データベースに永続化する必要がある新しい「PlaylistItem」オブジェクトを作成する機能があります。
  • ユース ケースでは、PlaylistItem を表示する前にクライアントがサーバーからの応答を待つ必要がないように、PlaylistItem を作成する必要があります。
  • クライアントは PlaylistItem の UUID を生成し、クライアントに PlaylistItem を表示してから、保存コマンドをサーバーに発行します。

この時点で、クライアントによって生成された UUID をデータベース内のオブジェクトの PK として使用するのは適切ではないことを理解しています。これは、悪意のあるユーザーが生成された UUID を変更し、DB で PK の衝突を強制する可能性があるためです。

PlaylistItem で PK の衝突を強制することで発生する損害を軽減するために、PK を 2 つの ID (クライアント生成の UUID とサーバー生成の GUID) の合成として定義することにしました。サーバーによって生成された GUID は、PlaylistItem のプレイリストの ID です。

さて、私はしばらくの間このソリューションを使用してきましたが、なぜ私のソリューションが単にクライアント ID を信頼するよりも優れているのか理解できません。ユーザーが別のユーザーの PlaylistItem オブジェクトとの PK 衝突を強制できる場合、そのユーザーの PlaylistId も提供できると想定する必要があります。彼らはまだ衝突を強制することができました。

だから...ええ。このようなことをする適切な方法は何ですか?クライアントが UUID を作成できるようにします。サーバーは、正常に保存されたときに親指を立てたり下げたりします。衝突が見つかった場合、クライアントの変更を元に戻し、衝突が検出されたことを通知しますか?

4

2 に答える 2

4

クライアントが生成した UUID またはサーバー上の同様のグローバル一意識別子を信頼できます。賢明にそれをしてください。

ほとんどのテーブル/コレクションも userId を保持するか、FK を介して userId に関連付けることができます。

挿入を行っていて、悪意のあるユーザーが既存のキーを使用している場合、レコード/ドキュメントが既に存在するため、挿入は失敗します。

更新を行っている場合は、ログインしているユーザーがそのレコードを所有しているか、更新する権限 (管理者ユーザーなど) を持っていることを検証する必要があります。純粋な所有権が強制されている場合 (つまり、管理者ユーザー シナリオがない場合) where、レコード/ドキュメントを検索する句に Id と userId の両方が含まれます。Id は 1 つのレコード/ドキュメントを一意に見つけるため、技術的に userId は where 句で冗長です。ただし、userId を追加すると、悪意のあるユーザーではなく、更新を行っているユーザーにレコードが属していることを確認できます。

サーバーが userId を確認するために復号化している暗号化されたトークンまたはセッションがあり、これがクライアントによって提供されていない場合、それは明らかに安全ではないと想定しています。

于 2016-08-28T02:57:57.050 に答える
3

良い解決策は次のとおりです: Sam Newman の「Building Microservices」を引用するには:

呼び出し元のシステムは BatchRequest を POST し、おそらくすべてのデータを含むファイルを配置できる場所を渡します。カスタマー サービスは HTTP 202 応答コードを返します。これは、要求が受け入れられたが、まだ処理されていないことを示します。呼び出し元のシステムは、要求が満たされたことを示す 201 Created を取得するまで待機しているリソースをポーリングできます。

したがって、あなたの場合、サーバーに POST できますが、すぐに「PlaylistItem を保存し、その Id がこれになることを約束します」のような応答を受け取ります。クライアント (およびユーザー) は、サーバー (おそらく API ではなく、API からメッセージを受け取った一部のバックグラウンド プロセッサ) がエンティティを保存するまで、処理、検証、その他のおそらく重いロジックの実行に時間をかけている間、続行できます。前述のように、API はそのリクエストのステータスの GET エンドポイントを提供でき、クライアントはそれをポーリングして、エラーが発生した場合に応じて動作できます。

于 2015-02-27T11:43:22.160 に答える