6

RESTAPIを介してユーザーパスワードを変更したい。これは、パスワードを忘れたりリセットしたりする機能ではありませんが、パスワードを変更したいログインユーザーです。

フォームには、現在のパスワード、新しいパスワード、および新しいパスワードの確認が必要です。ただし、ユーザーが入力するときに各フォームフィールドを検証したいと思います。newPasswordこれはとconfirmNewPassword(クライアント側)にとっては些細なことですが、。にとってはそうではありませんcurrentPassword。現在、を介してUserオブジェクトの更新を実行していますPUT /users/:id。パスワードパラメータが渡された場合、currentPassword保存する前にパラメータをチェックして正しいことを確認します。ただし、検証のために、最善のアプローチがわかりません。

私も持っていますPOST /users/validate-これが最善かどうかはわかりません。emailこれにより、作成と更新の両方についてUserオブジェクトが検証されますが、Userオブジェクト( 、、 )usernameに属するフィールドのみが検証されますpasswordcurrentPasswordこれらの1つではありません。これをどのように処理するか疑問に思います。私が考慮したいくつかのこと:

POST /users/check_passwordPOST /users/validate(そのパラメーターが渡された場合はcurrentPasswordの検証を追加し、currentPasswordがユーザーの既存のパスワードと一致することを確認します)および POST /users/:id/validate(既存のユーザーの個別の検証、必須currentPassword)。

任意の考えやアドバイスをいただければ幸いです。RESTAPIを介してのみ機能を公開する私の最初のアプリケーション。

4

5 に答える 5

8

認証は多くの場合、REST モデルの外部で処理されることを指摘することから始めます。ユーザーが資格情報を提供するとき、アカウント オブジェクトの STate (REST) の REpresentation を提供していません。また、彼らが受け取る応答もそのような表現ではありません。ユーザー アカウント リソースの状態には「現在の」パスワードと「新しい」パスワードの両方が含まれていないため、リクエストで「現在の」パスワードと「新しい」パスワードの両方を提供することは、REST モデルに真に適合することはありませんが、専門家はしばしば、一部の API は完全に RESTful であり、他の API は RPC (リモート プロシージャ コール) と REST の中間に位置します。

データ モデルの提供を処理する API の RESTful コンポーネントと、ユーザー アカウントを処理する API のより多くの RPC コンポーネントを持つことは珍しくありません。あなたは2つの間で決めることができます。プロジェクトに複数のユーザー アカウントを管理するスーパー ユーザーが含まれている場合は、それを REST API に押し込むことをお勧めします。各ユーザーが自分のアカウントのみを管理する場合は、RPC をお勧めします。

アカウント管理に REST を使用することにした場合は、適切な HTTP メソッド (GET、POST、DELETE、HEADERS など) を選択する必要があります。明らかに、サーバーに変更を加えるメソッド (POST、PUT、DELETE など) が必要です。上記のユーザー orbfish の結論とは対照的に、特定の制限の下では、PUT が適切な方法であると言うつもりです。

HTTP メソッドを正式に定義するRFC 2616から:

「メソッドは、(エラーまたは有効期限の問題を除いて)N > 0の同一リクエストの副作用が単一のリクエストと同じであるという点で、「冪等性」のプロパティを持つこともできます。GET、HEAD、PUT、およびDELETEメソッドは、このプロパティ。また、メソッド OPTIONS と TRACE SHOULD NOT には副作用があるため、本質的に冪等です。」

ここでの冪等性とは、同じリクエストをn回続けて行う場合、n番目のリクエストの影響下でのサーバーの状態が、最初のリクエストの影響下でのサーバーの状態と同じになることを意味します。ユーザーorbfishは、リクエストを行うと次のことを正しく指摘しています。

PUT /users/:id/account {current-password: 'a', new-password: 'b'}

そしてそれを繰り返します:

PUT /users/:id/account {current-password: 'a', new-password: 'b'}

最初のリクエストは成功を示すレスポンスを受け取り、2 番目のリクエストは失敗を示すレスポンスを受け取る必要があります。ただし、PUT の冪等性は、サーバーの状態が両方の要求に続いて同じであることのみを必要とします。つまり、最初の要求の後、ユーザーのパスワードは 'b' になり、2 番目の要求の後、ユーザーのパスワードは 'b' になります。

上記の制限について説明しました。mがパスワードの変更に失敗した後、ユーザーをロックアウトすることができます。これにより、ブルート フォース パスワード攻撃に対するセキュリティが提供されます。ただし、これはリクエストの冪等性を壊します: 有効なパスワードリクエストを 1 回送信し、パスワードを変更し、それをさらにm回送信すると、サーバーはあなたをロックアウトします。

PUT メソッドを指定することで、必要な回数だけリクエストを送信しても安全であることをすべてのクライアントに伝えます。私がクライアントとして PUT リクエストを送信し、接続が中断されて応答を受信できない場合、冪等であるため、再度 PUT を送信しても安全であることがわかっています。冪等性とは、両方のリクエストを受信した場合に、サーバーにとっては、受信するだけと同じになります。ただし、リクエストが失敗したためにロックアウトする場合は、最初のリクエストを受け取ったかどうかを確認するまで、2 番目のリクエストを送信するのは安全ではありません。

このため、PATCH または POST を検討してください。PATCH を使用することをお勧めします。POST は、リストに新しいリソースを追加するか、既存のリソースにデータを追加するものとして説明されますが、PATCH は、既知の URI にあるリソースの「部分的な更新」として説明されます。また、PUT とは異なり、PATCH は冪等である必要はありません。

于 2015-01-06T20:58:48.913 に答える
7

/check_password や /validate は動詞なので好きではありません。最初の「更新ユーザー」は REST の方が優れています。

currentPassword を永続化されていないフィールドとして、または認証ヘッダー (username:password) の一部として User オブジェクトに追加できます。

ただし、同じ currentPassword を使用した同じ呼び出しは 2 回成功できないため (PUT はべき等です)、これを PUT から POST に変更することは間違いありません。

于 2014-01-06T20:32:21.073 に答える
2

もう 1 つのオプションは、代理​​リソースを に作成することuserです。HATEOAS を使用している場合はuser/x/pwdchangeuserリソースからリンクできます。pwdchangeそして、動詞としてではなく、名詞/リソースとして考えられていることを明確にしたいと思います。

GET /user/jsmith/pwdchange     List of password change requests (history)
POST /user/jsmith/pwdchange    Create password change request, return id=1
GET /user/jsmith/pwdchange/1   Get password change resource, which would
                               include the outcome (success, failure, etc)

要するに、問題ドメインの REST ビューに完全に準拠した「pwdchange」という名前のリソースを作成しています。

于 2016-03-29T13:15:54.117 に答える
1

現在のパスワードを入力したらすぐに検証する必要がある理由について考えるかもしれません。私はそれを行うサイトを見たことがありません。第 2 に、何かを検証するだけのサービスを用意してもまったく問題ありません。それは実用的な詩であると呼ばれ、RESTFulになろうとして自分を打ち負かします

于 2011-11-23T12:57:40.707 に答える