これを理解するのを手伝ってくれませんか?「一般的なRESTの間違い:セッションは無関係です」


159

免責事項:私はRESTの考え方に慣れていないので、RESTスクールに集中しようとしています。

したがって、私はこのページ、「一般的なRESTの間違い」を読んでおり、関連性のないセッションのセクションに完全に困惑していることがわかりました。これはページが言うことです:

クライアントが「ログイン」または「接続を開始」する必要はないはずです。HTTP認証はすべてのメッセージで自動的に行われます。クライアントアプリケーションは、サービスではなくリソースのコンシューマです。したがって、ログインする必要はありません。REST Webサービスでフライトを予約しているとしましょう。サービスへの新しい「セッション」接続を作成しません。むしろ、「旅程作成者オブジェクト」に新しい旅程を作成するように依頼します。空白を埋め始めることができますが、その後、Webの他の場所にまったく異なるコンポーネントを取得して、他の空白を埋めることができます。セッションがないため、クライアント間でセッション状態を移行する問題はありません。「セッションアフィニティ」の問題もありません

さて、HTTP認証はすべてのメッセージで自動的に行われることになりますが、どうやって?ユーザー名/パスワードはすべてのリクエストで送信されますか?それだけで攻撃の表面積が増えるのではないですか?パズルの一部が欠けているような気がします。

たとえば、/sessionGETリクエストを受け入れ、リクエストの一部としてユーザー名/パスワードを渡し、認証が成功した場合にセッショントークンを返すRESTサービスがあると悪いでしょう。後続のリクエストと一緒に渡されましたか?それはRESTの観点からは理にかなっていますか、それともポイントが不足していますか?


すべてのリクエストは常に認証され、セッションハイジャックは重要です。restfulは、これをより明白にしますが、より露出しません。
Jasen

回答:


79

RESTfulであるためには、各HTTPリクエストは、受信者がHTTPのステートレスな性質と完全に調和するように処理するために、それ自体で十分な情報を運ぶ必要があります。

さて、HTTP認証はすべてのメッセージで自動的に行われることになりますが、どうやって?

はい、ユーザー名とパスワードはリクエストごとに送信されます。これを行う一般的な方法は、基本アクセス認証ダイジェストアクセス認証です。そして、はい、盗聴者はユーザーの資格情報を取得できます。したがって、トランスポート層セキュリティ(TLS)を使用して送受信されるすべてのデータを暗号化します。

GETリクエストを受け入れ、リクエストの一部としてユーザー名/パスワードを渡し、認証が成功した場合にセッショントークンを返すRESTサービス、たとえば/ sessionがあると悪いのではないでしょうか。その後のリクエストと一緒に渡されますか?それはRESTの観点からは理にかなっていますか、それともポイントが不足していますか?

これはRESTfulではありません状態をため、ユーザーにとって便利であるため、非常に一般的です。ユーザーは毎回ログインする必要はありません。

「セッショントークン」で記述したものは、通常、ログインCookieと呼ばれます。たとえば、Yahoo!にログインしようとすると、アカウントには、「2週間ログインしたままにする」というチェックボックスがあります。これは基本的に(あなたの言葉で)「ログインに成功した場合、セッショントークンを2週間保持する」と言っています。Webブラウザーは、ユーザーが要求するHTTP要求ごとに、そのようなログインCookie(および場合によってはその他)を送信します。


5
この答えは私には意味がありません。まず、ログインとパスワードを毎回、つまり1回渡すことは問題ないということです。次に、成功したログイン状態をトークンの形式でクライアントに返すというアイデアが提案されています。必要に応じて、トークンは作成時間をエンコードできます。私たちは確かにクライアントに情報を返すことを許可されています。したがって、この提案は私には問題ないようです。答えは、「状態を運ぶ」ので問題ないということですが、「REST」の「ST」という考え方は、クライアントとサーバーの間で状態を転送できるのではないでしょうか。

33

RESTサービスがすべてのHTTPリクエストに対して認証を要求することは珍しくありません。たとえば、Amazon S3では、すべてのリクエストに、ユーザーの認証情報、実行する正確なリクエスト、および現在の時刻から派生した署名が必要です。このシグネチャは、クライアント側で簡単に計算でき、サーバーですばやく検証でき、(現在の時刻に基づいているため)傍受する攻撃者に限定的に使用されます。


3
+1について詳しく説明してください:(現在の時刻に基づいているため)傍受する攻撃者の使用は限られていますか?暗号化されたユーザー名とパスワードを含むクッキーについて話していませんか?のように?(私見)
Royi Namir 2013

2
@RoyiNamir:私はクッキーについて話しているのではありません。S3で使用される署名はHTTPリクエストのパラメーターです、Cookieではなく、リクエストごとに再計算されます。
グレッグ・ヒューギル2013

ユーザーに関する情報を保存する必要がある場合、どこに保存すればよいですか?dbで?各リクエストをdbに送りたくありません。
Royi Namir 2013

@RoyiNamir:目標を達成する方法について具体的な質問がある場合は、新しい質問をしてください。ここでコメントで追加の質問に答えることはできません。
グレッグ・ヒューギル2013

10

多くの人はRESTプリンシパルをあまり明確に理解していません。セッショントークンを使用しても、常にステートフルであるとは限りません。各リクエストでユーザー名/パスワードを送信する理由は、認証のためだけであり、トークンを送信するためと同じです(ログインによって生成されます)プロセス)クライアントにデータをリクエストする権限があるかどうかを判断するためだけに、ユーザー名/パスワードまたはセッショントークンのいずれかを使用して、表示するデータを決定する場合にのみRESTの違反に違反します!代わりに、それらを認証のためにのみ使用する必要があります(データを表示するか、またはデータを表示しないため)

あなたのケースでは私はYESと言っていますが、これはRESTyですが、REST APIでネイティブのphpセッションを使用しないようにして、決められた期間で期限切れになる独自のハッシュトークンの生成を開始してください!


1
ありがとうございました。なぜネイティブのPHPセッションを避け、代わりに独自のハッシュトークンを使用する必要があるのですか?
マシュー

セキュリティと制御を強化するためだけに、私が言う素晴らしい理由はありません。
EvilThinker 2015年

これは受け入れられた答えよりも優れています。少なくとも、提案をRESTyとして受け入れます。これは理にかなっています。ただし、渡された情報を使用してユーザー依存の認証を実行できない理由はわかりません。一部のユーザーは一部のデータにアクセスでき、他のユーザーはアクセスできない場合があります。それによってプロトコルがRESTfulにならないわけではありません。

8

いいえ、要点を見逃しません。GoogleのClientLoginは、クライアントがHTTP 401応答を使用して「/セッション」に移動するように指示されていることを除いて、まったく同じように機能します。ただし、これによってセッションが作成されるわけではありません。クライアントが(一時的に)資格情報を平文で渡さずに自分自身を認証し、サーバーがこれらの一時的な資格情報の妥当性を適切に制御する方法を作成するだけです。


11
@ unforgiven3返されたトークンがユーザーの認証にのみ使用され、サーバーに格納されている他の状態にユーザーを関連付けるためにサーバーによって使用されない限り、REST制約に違反していないことがわかります。
Darrel Miller、

4
@ unforgiven3サーバーから返されるトークンは、実際には、ユーザーが本人であることを証明するものです。したがって、ユーザー名とパスワードを含む各リクエストの代わりに、各リクエストには、サーバーがその信憑性に自信を持つことができるように構築されたトークンが含まれています。
Darrel Miller、

1
@ unforgiven3、ダレルは正しい。エコーバックされるトークンは、トークンの有効期限が切れるまで、基本的なダイジェスト認証と同様に、すべてのHTTPリクエストでクライアントから送信される必要があります。その場合、クライアントはログインを繰り返すことができ、オプションでユーザーに資格情報などを要求します。必要に応じて、答えを詳しく説明することができます。 編集:(そして、古い質問への回答についていくのをありがとう!)
mogsie

1
問題ありません、モグジー、これらのタイプのことを話し合うのはいつも面白いです:-)私はあなたたちがこれでどこに向かっているのかを見ていますトークンが各HTTPリクエストに返送される方法を理解していますが、これは実装の詳細のようです)。ただし、この方法がRESTの原則に違反しない理由がわかります。回答ありがとうございます!
Rob

6
@ unforgiven3、これは役立つかもしれません:トークンは署名された情報です。したがって、それは自己完結型です。サーバーは、以前に保存された状態をチェックせずにトークンを検証できます。したがって、クライアントに格納され、前後に転送されるのは単なる状態です。
Iravanchi 14年

5

さて、HTTP認証はすべてのメッセージで自動的に行われることになりますが、どうやって?

「Authorization:」クライアントが送信したHTTPヘッダー。基本(プレーンテキスト)またはダイジェスト。

GETリクエストを受け入れ、リクエストの一部としてユーザー名/パスワードを渡し、認証が成功した場合にセッショントークンを返すRESTサービス、たとえば/ sessionがあると悪いのではないでしょうか。その後のリクエストと一緒に渡されますか?それはRESTの観点からは理にかなっていますか、それともポイントが不足していますか?

セッションの全体的な考え方は、サーバー側の状態を維持することにより、ステートレスプロトコル(HTTP)とダムクライアント(Webブラウザ)を使用してステートフルアプリケーションを作成することです。RESTの原則の1つは、「ハイパーメディアリンクで使用するためのユニバーサル構文を使用して、すべてのリソースを一意にアドレス指定できる」です。セッション変数は、URIを介してアクセスできないものです。真にRESTfulなアプリケーションはクライアント側で状態を維持し、必要なすべての変数をHTTP経由で、できればURIで送信します。

例:ページネーション付きの検索。フォームにURLがあります

http://server/search/urlencoded-search-terms/page_num

ブックマーク可能なURLと多くの共通点があります


4
ただし、認証情報にはURI経由でもアクセスできません-誰もがリクエストヘッダーの一部として認証情報を送信することについて話し合っています。リクエストにセッショントークンを含めるのとどう違うのですか?セッショントークンをURIで使用するのではなく、リクエストで渡されるデータで使用することを言っています。
Rob、

認証は、そのアクションを実行する権限がある場合に確立され、RESTfulアプリケーションでは結果に影響しません。
vartec 2009

4
セッショントークンは、そのアクションを実行する権限があるかどうかも確立します。結果に影響を与えないとはどういう意味ですか?呼び出し元が承認されていない場合、Not Authorizedエラーが発生します。セッショントークンについても同じことが言えます。本当に違いがわかりませんか?
Rob、

3
いいえ、セッショントークンはサーバーに保存された状態へのハンドルです。それはRESTfulではありません。Not Authorizedについては、その結果はわかりません。(try / catchの場合のように)むしろその例外を検討したいと思います。
vartec、2009

十分に公正な、vartec-それは理にかなっています。フォローアップありがとうございます!
Rob

3

クライアントセッションのライフタイムを制御したい場合は、提案は問題ないと思います。RESTfulアーキテクチャーは、ステートレスアプリケーションの開発を促進すると思います。@ 2penceが書いたように、「各HTTPリクエストは、受信者がHTTPのステートレスな性質と完全に調和するように処理するために、それ自体で十分な情報を運ぶ必要があります」

ただし、常にそうであるとは限りません。アプリケーションは、クライアントのログインまたはログアウトのタイミングを通知し、この情報に基づいてロックやライセンスなどのリソースを維持する必要がある場合があります。そのような場合の例については、私のフォローアップの質問を参照してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.