22

SOでこれを行う方法の例を見てきましたが、私が知る限り、これまでのところ成功していないすべての例を試しました。いくつかの実装をシナリオに合わせて変更しようとしましたが、これもこれまでのところ失敗しています。

これは _layout.cshtml のページにあるため、常にトークンを使用できます。

<form id="__AjaxAntiForgeryForm" action="#" method="post"> @Html.AntiForgeryToken()</form>

JavaScript utils ファイルにもこのメソッドがあります。

AddAntiForgeryToken = function (data) {
    data.__RequestVerificationToken = $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val();
    return data;
};

これはすべて期待どおりに機能しており、偽造防止トークンを取得しています。私の実際の投稿コードは次のとおりです。

myPage.saveData = function() {
    var saveUrl = '/exercises/PostData';

    var myData = JSON.stringify(myPage.contextsArrays);

    $.ajax({
        type: 'POST',
        async: false,
        url: saveUrl,
        data: AddAntiForgeryToken({ myResults: myData }),
        success: function () {
            alert('saved');
        },
        dataType: 'json',
        contentType: "application/json; charset=utf-8"
    });
};

私のアクションメソッドは次のようになります。

    [HttpPost, ValidateAntiForgeryToken, JsonExceptionFilter]
    public JsonResult PostData(List<ResultsDc> myResults)
    {
        return Json(_apiClient.SubmitResults(myResults));
    }

私が試してきたさまざまな実装でこれをテストしてきましたが、応答は常に次のとおりです。

{"errorMessage":"The required anti-forgery form field \"__RequestVerificationToken\" is not present."}

フォームを投稿するのではなく、単なるデータの配列ですが、実際に投稿されるデータを確認すると、Json が正しく見えません (すべてエンコードされています) が、__RequestVerificationToken パラメーター名があり、トークン値も存在します。

現時点では、これらすべてにかなり混乱しており、MVC アクションが呼び出されるようにトークンを送信する正しい方法を見つけることができません。ValidateAntiForgeryToken属性を削除しJSON.stringify(myPage.contextsArrays);てデータとして持つと、json は正しく (エンコードされていない) ように見え、正常にマップされます。

このトークンをフォームなしで適切に投稿するにはどうすればよいですか?

4

3 に答える 3

35

Cardboard 開発者が再びストライキを行います。

私がしなければならなかったのは、削除することだけでした:

contentType: "application/json; charset=utf-8"

そして、それを行うことで (作成される投稿リクエストの種類が変更されます)、実際のデータ プロパティのJsonTコンテンツを取得して、モデル タイプに正しくバインドする必要があります。 JSON.stringify()

于 2013-07-25T12:47:56.850 に答える
17

(注:これはすでにここにあるものとそれほど変わらないことを私は知っています)

これはすでに回答されていることを認識していますが、これをかなり行ったので、私の回答を山に追加します。私のサイトにはフォームがないので、これを処理する方法を考え出さなければなりませんでした。ここでのスタックオーバーフローといくつかのブログに関する多くの調査により、最終的に必要な情報が得られました。

まず、「マスター」ページ (MVC Razor) の上部にあるコードは次のとおりです。

@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "__AjaxAntiForgeryForm" }))
{
    @Html.AntiForgeryToken()
}

次に、すべての ajax 呼び出し (jQuery) で、次のように開始します。

var token = $("#__AjaxAntiForgeryForm input").val();
var dataObject = {
  __RequestVerificationToken: token,
  myData: "whatever"
};

$.ajax({
  url: '@Url.Action("action", "controller")',
  type: 'POST',
  dataType: 'json',
  data: dataObject,
  error: function (jqXHR, textStatus, errorThrown) {
    console.log("ERROR!");
  },
  success: function (data) {
    //whatever
  }
});

最後に、コントローラー側では、これは正常に機能します。

public class controllerController : Controller
{
    [HttpPost]
    [ValidateAntiForgeryToken]
    public JsonResult action (myModel myData)
    {
        return Json(new { Success = "true" }, JsonRequestBehavior.DenyGet);
    }
}

うまくいけば、これは同じボートに乗っている他の人を助けるでしょう.

于 2014-10-30T17:02:40.667 に答える
1

検証は、フォーム データを参照するようにハードコーディングされています。

https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.WebPages/Helpers/AntiXsrf/AntiForgeryTokenStore.cs

    public AntiForgeryToken GetFormToken(HttpContextBase httpContext)
    {
        string value = httpContext.Request.Form[_config.FormFieldName];

特定のフォーマットに従うことで、フォーム送信をシミュレートできます。そのためには、POST リクエストで HTML フォームの送信を模倣する方法を参照してください。

必要に応じて、独自のバリデータを作成することもできます。ValidateAntiForgeryToken を使用して JSON データを Asp.Net MVC 2 アプリに POSTする方法では、これを行う方法について説明しています。これは MVC 2 用ですが、そこからいくつかのアイデアを得ることができます。

于 2013-07-25T12:38:35.410 に答える