11

この質問は、一般的なWebアプリのログインフローに関する質問です。セキュリティを維持しながら、使いやすさとパフォーマンスを最適化する回答に最も興味があります。

ブックマークされたURLへの認証されていないリクエストを処理するための最も適切な方法は何ですか?

問題を示すために、サンプルアプリケーションのいくつかのルートとそれぞれの動作を次に示します。

GET /login         -> Display the authentication form
POST /processLogin -> process the username and password, 
                            if unauthentic...re-render the login form; 
                            otherwise...display the default page
GET /secret         -> if authenticated...display the secret resource;
                       otherwise...display a login form
POST /secret        -> if authenticated...perform a desirable, but potentially 
                                          non-idempotent action on the secret 
                                          resource
                       otherwise...display a login form

オプション1:ログイン画面を表示し、目的のページにリダイレクトします

  1. ユーザーがブックマークをクリックする
  2. GET / secret-> 200、隠しフィールドpath ="/secret"を使用してログインフォームを密かに表示する
  3. POST / processLogin-> 302 to / secret(パスパラメータの値)
  4. GET / secret-> 200、シークレットリソースが表示されます

分析:うまくいけば、クライアントはHTTPに準拠していない最新のブラウザーであり、302のPOSTの後にGETを実行します。これは全面的に適用されます。心配する必要がありますか?

オプション2:ログイン画面にリダイレクトし、目的のページにリダイレクトします

  1. ユーザーがブックマークをクリックする
  2. GET / secret-> 302 to / login
  3. リダイレクトを介して/loginを取得->200、隠しフィールドpath ="/secret"で表示されたログインフォーム
  4. POST /processLogin->302から/secret
  5. GET / secret-> 200、シークレットリソースが表示されます

分析:上記と同じ問題。ログイン中にブラウザに表示されるURLが変更されると、ユーザーが混乱し、ブックマークやリンクの共有などが中断するという問題が追加されました。

オプション3:ログイン画面を表示し、目的のページを表示します

  1. ユーザーがブックマークをクリックする
  2. GET / secret-> 200、アクション="/secret"を含むログインフォームを密かに表示する
  3. POST / secret-> 200、シークレットリソースが表示されます

分析:残念ながら、更新ボタンも壊れています。更新すると、ユーザーエージェントは/ secretを再取得する代わりに、警告付きで再POSTします。ユーザーは警告を受け取りますが、それを無視すると、何か悪いことが起こります。

明るい面では、この手法を使用してラウンドトリップを最小限に抑えます。

オプション4:ログイン画面にリダイレクトし、目的のページを表示します

  1. ユーザーがブックマークをクリックする
  2. GET /secret->302から/processLogin
  3. リダイレクトを介して/processLoginを取得->200、アクション="/secret"で表示されるログインフォーム
  4. POST /secret->302から/secret
  5. GET / secret-> 200、シークレットリソースが表示されます

分析:オプション2+4と同じ問題。

オプション5:???

私が見逃している別のテクニックはありますか?

一般的に、これらのテクニックのどれをお勧めしますか?

関連項目

ログインページにリダイレクトするときの正しいHTTPステータスコードは何ですか? ログイン用のHTTPリダイレクトの種類は何ですか? リダイレクトありのHTTP応答ですが、ラウンドトリップはありませんか?

4

5 に答える 5

5

オプション 1 と 3 はHTTP RFCに従っていません。「ログイン フォームをひそかに表示する」が 200 GET 応答と矛盾し、「要求されたリソースに対応するエンティティが応答で送信される」ことが予想されるためです。

オプション 2 は問題ありません。最新のブラウザーはすべて POST で 302 をサポートしており、多くの REST ベースのフレームワーク (RoR など) が積極的に使用しています。または、「302 to /login」で、元の URL を GET パラメーターに渡さないように、セッション (Cookie) を作成して URL をセッションに保存することもできます。使いやすさの観点から、ログインページにも適切なメッセージを表示できます (ここでは URL の不一致は関係ないと思います - とにかくユーザーにコンテンツを表示させることはできません)。

オプション 4: /secret に POST するとき、HTTP RFC は「リクエストに含まれるエンティティを、リクエスト ラインのリクエスト URI で識別されるリソースの新しい下位として受け入れる」ことを期待していますが、行っているのはログ記録だけです。 /secret の下に新しいものを作成しません。

したがって、HTTP RFC に従うと、最良の選択はオプション 2です。実際、オプション 2 は POST->Redirect->GET design patternとも一致しており、POST されたリソースへの URL をブックマークする際の予測不可能性の問題に対処するのに役立ちます。

于 2013-03-14T09:39:30.177 に答える
3

My $.02: 最近、オプション 2 を使用して実装しました (ただし/secret、隠しフィールドとしてログイン フォームではなく、セッションに保存しました)。

私はあなたの懸念を完全に共有しているわけではありません:

ログイン時にブラウザに表示される URL が変更され、ユーザーが混乱し、ブックマークやリンク共有などが機能しなくなるという問題を追加しました。

へのリダイレクト/loginとその後の URL の変更により、続行する前に、最初に行う必要があることが他にあることをユーザーに伝えます。それはログインです。

ログインページは「ターゲットページ」とはまったく異なるように見えるため、ターゲットページではなくログインページをブックマークしたりリンクを共有したりすることに人々がどのように混乱するかはわかりません(ログインページにはとにかくブックマーク/共有したい情報)。

また、302 が標準に違反するのではないかと心配している場合 (私が知っているすべてのブラウザーは喜んで標準を破りますが)、代わりに 303 を使用することを検討してください。

于 2013-03-09T15:23:34.970 に答える
1

mickeyreiss が正しいことに注意してください。AJAX オプション 3 を使用すると、壊れた [戻る] ボタンの欠点なしで機能します。ただし、これは、ユーザーが JavaScript を有効にする必要があることを意味します。そうは言っても、フォームを適切にプログラムすれば、JS が存在するかどうかを検出できます。そうでない場合は、オプション 1 を使用します。

302 応答は問題ありませんが、キャッシュに問題がある可能性があることに注意してください。同じ URI に対して 2 つの完全に異なるページ/フォームを表示する場合は、何もキャッシュされないようにする必要があります。(/secret はログインを表示し、次に実際のシークレットを表示します。)

于 2013-03-09T11:01:55.220 に答える
1

URL によって返されるコンテンツが一貫しているという理由だけで、ほとんどの場合、オプション #2 を使用します。今日のシークレットはログインの背後に隠されていますが、明日は、同じ URL での認証に応じて、公開したり、公開/シークレットを混在させて表示したりすることができます。その場合、オプション #2 は、Google が期待するものに最も似ています。コンテンツのおとり商法は Google に見下され、極端な場合、すべてのページに重複したページ コンテンツ (ログイン フォームなど) が表示されます。

于 2013-03-14T19:09:10.660 に答える
0

私はAJAXを使用してオプションを選択します:

  1. ログインページとコンテンツを非表示
  2. ユーザーはログインとパスワードを入力します。
  3. 認証はサーバー側で行われます。
  4. サーバーは結果を返します
  5. location.href移動したいページを設定するためにうまく使用された場合、またはログインが無効であることを示すメッセージを出力することができます。
  6. _SESSIONログインページへのリダイレクトが設定されていない場合、サーバーで変数をテストします。
于 2013-03-14T19:05:47.703 に答える