8

私が構築しているページは、AJAX に大きく依存しています。基本的に、「ページ」は 1 つだけで、すべてのデータ転送は AJAX を介して処理されます。ブラウザー側で過度に楽観的なキャッシングを行うと奇妙な問題 (データがリロードされない) が発生するため、POST を使用してすべての要求 (読み取りも) を実行する必要があります。これにより、リロードが強制されます。

ここで、CSRF に対してページを防止したいと考えています。フォームHtml.AntiForgeryToken()送信ではうまく機能しますが、AJAX リクエストでは、トークンを手動で追加する必要があると思いますか? すぐに使用できるものはありますか?

私の現在の試みは次のようになります

既存の魔法を再利用したい。ただし、HtmlHelper.GetAntiForgeryTokenAndSetCookieプライベートであり、MVC をハックしたくありません。他のオプションは、次のような拡張機能を作成することです

public static string PlainAntiForgeryToken(this HtmlHelper helper)
{
    // extract the actual field value from the hidden input
    return helper.AntiForgeryToken().DoSomeHackyStringActions();
}

これはいくぶんハックであり、より大きな問題を未解決のままにします:そのトークンを確認する方法は? デフォルトの検証の実装は内部であり、フォーム フィールドの使用に対してハードコードされています。少し変更した を書こうとしましたValidateAntiForgeryTokenAttributeが、AntiForgeryDataSerializerそれは非公開の を使用しており、それもコピーしたくありませんでした。

現時点では、自家製のソリューションを考え出す方が簡単に思えますが、それは実際には重複したコードです。

これをスマートな方法で行う方法について何か提案はありますか? 完全に明らかな何かが欠けていますか?

4

1 に答える 1

10

従来のHtml.AntiForgeryToken()ヘルパーを使用して、ページのどこかに隠しフィールドを生成し (フォーム内である必要はありません)、ajax リクエストに含めることができます。

var token = $('input[name=__RequestVerificationToken]').val();
$.post(
    '/SomeAction', { '__RequestVerificationToken': token }, 
    function() {
        alert('Account Deleted.');
    }
);

サーバー側で確認するには:

[AcceptVerbs(HttpVerbs.Post)]
[ValidateAntiForgeryToken]
public ActionResult SomeAction() 
{
    return View();
}

ページに複数のトークンがある場合、含めるトークンを指定する必要がある場合があります。既存のヘルパーは同じ名前の非表示フィールドを生成するため、適切なセレクターを作成するのは難しいため、それらをスパン内に配置できます。

<span id="t1"><%= Html.AntiForgeryToken() %></span>
<span id="t2"><%= Html.AntiForgeryToken() %></span>

次に、対応するトークンを選択します。

var token = $('#t1 input[name=__RequestVerificationToken]').val();
于 2010-02-28T09:04:03.340 に答える