web-dev-qa-db-ja.com

必要な偽造防止Cookie「__ RequestVerificationToken」が存在しません

私のウェブサイトはこの例外を1日に約20回発生させています。通常、フォームは正常に機能しますが、この問題が発生する場合があり、なぜそれほどランダムなのかわかりません。

これはelmahによって記録された例外です

500 HttpAntiForgery必要な偽造防止Cookie __RequestVerificationToken "が存在しません。

しかし、elmahがXMLログに示すように、トークンを送信しているフォーム

<form>
    <item name="__RequestVerificationToken">
      <value string="DNbDMrzHmy37GPS6IFH-EmcIh4fJ2laezIrIEev5f4vOhsY9T7SkH9-1b7GPjm92CTFtb4dGqSe2SSYrlWSNEQG1MUlNyiLP1wtYli8bIh41"/>
    </item>
    <item name="toPhone">
      <value string="XXXXXX"/>
    </item>
    <item name="smsMessage">
      <value string="xxxxxxxx"/>
    </item>
</form>

これは、データ属性を使用してトークンが有効かどうかを確認するコントローラー上の私のメソッドです

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<JsonResult> Send(SMSModel model)
{
    // my code goes here
}

これはビュー上の私のフォームです

@using (Html.BeginForm("Send", "SMS", FormMethod.Post, new { @class = "form-sms", autocomplete = "off" }))
{
    @Html.AntiForgeryToken()
    <div class="row">
        <div class="col-md-12">
            <div class="form-group">
                <div class="input-group">
                    <div class="input-group-addon">+53</div>
                    @Html.TextBoxFor(m => m.toPhone, new { @class = "form-control", placeholder = "teléfono", required = "required", type = "tel", maxlength = 8 })
                </div>
            </div>
        </div>
    </div>
    <div class="form-group" style="position:relative">
        <label class="sr-only" for="exampleInputEmail3">Message (up to 135 characters)</label>
        @Html.TextAreaFor(m => m.smsMessage, new { rows = 4, @class = "form-control", placeholder = "escriba aquí su mensaje", required = "required", maxlength = "135" })
        <span class="char-count">135</span>
    </div>
    if (ViewBag.Sent == true)
    {
        <div class="alert alert-success alert-dismissible" role="alert">
            <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
            <strong>Su mensaje ha sido enviado <span class="hidden-xs">satisfactoriamente</span></strong>
        </div>
    }
    if (ViewBag.Error == true)
    {
        <div class="alert alert-danger alert-dismissible" role="alert">
            <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
            <strong>Error:</strong> Por favor revise el número de teléfono.
        </div>
    }
    <div class="errorToMany"></div>
    <button type="submit" class="btn btn-default btn-block">Enviar SMS</button>
}

そして、これはAJAXを使用してデータを投稿する方法です

$('form.form-sms').submit(function (event) {
    $.ajax({
        url: $(this).attr("action"),
        type: "POST",
        data: $(this).serializeArray(),
        beforeSend: function (xhr) {
            $('.btn-default').attr("disabled", true);
            $('.btn-default').html("Enviando...")
        },
        success: function (data, textStatus, jqXHR) {
            if (data[0] == false && data[1] == "1") {
               some code 
            } else {
               location.reload();
            }
        },
        error: function (jqXHR, textStatus, errorThrown) { }
    });
    return false;
});

フォームはほとんどの場合うまく機能しますが、このエラーが発生し続け、理由はわかりません。ここでStack Overflowの他の質問を確認しましたが、何も機能しません。

データの投稿方法の詳細については。

送信するこのフォームSMSにはToNumberおよびMessageフィールドがあります。ユーザーが送信ボタンをクリックすると、AJAX関数が制御を取得し、フォームのフィールドをシリアル化してポストしますデータ、コントローラー内の私の関数が終了し、すべてがうまくいったことを示すJSON結果を返すと、AJAXメソッドはページをリロードし、ユーザーに成功メッセージを表示します。

この問題を引き起こしている可能性のあるアイデア。

23

物事が期待どおりに機能しているように聞こえます。

偽造防止ヘルパー@Html.AntiForgeryToken()が機能する方法は、__RequestVerificationTokenという名前の非表示フォームフィールドをページに挿入し、ブラウザにCookieを設定することです。

フォームがポストバックされると、2つが比較され、それらが一致しないか、Cookieがない場合、エラーがスローされます。

したがって、フォームが__RequestVerificationTokenを送信していることをElmahがログに記録することは重要ではありません。 CSRF攻撃が発生した場合でも、これは単に非表示のフォームフィールドであるため、常にそうなります。

<input name="__RequestVerificationToken" type="hidden" value="DNbDMrzHmy37GPS6IFH-EmcIh4fJ2laezIrIEev5f4vOhsY9T7SkH9-1b7GPjm92CTFtb4dGqSe2SSYrlWSNEQG1MUlNyiLP1wtYli8bIh41" />

一方、エラーメッセージは、対応するCOOKIEが送信されていないことを示しています。

500 HttpAntiForgery必要な偽造防止Cookie __RequestVerificationToken "が存在しません。

したがって、基本的に誰か/何かがクッキーを取得するための元のリクエストを行わずにフォーム投稿を再生しています。そのため、非表示フォームフィールド__RequestVerificationTokenがありますが、検証するためのCookieはありません。

ですから、物事は本来のように機能しているようです。ログを再確認してください。IP番号、リファラーなど。フォームのコンテンツをリダイレクトするときに、攻撃を受けているか、何かおかしなことやバグがあるかもしれません。上記のように、referrersは、この種のエラーを開始するのに適した場所です。これはスプーフィングされていないことを前提としています。

[〜#〜] mdn [〜#〜]

location.reload();

Location.reload()メソッドは、現在のURLからリソースをリロードします。オプションの一意のパラメーターはブール値であり、trueの場合、サーバーから常にページが再ロードされます。 falseまたは指定されていない場合、ブラウザはキャッシュからページをリロードする場合があります

そうである場合、キャッシュからロードするときに、古いページトークンはあるがCookieはないPOSTになることがあります。

だから試してください:

location.reload(true);
21
rism

最近、同様の問題に遭遇しました。偽造防止Cookieが実際に欠落していたため、(他の人が指摘したように)

  1. サーバーがリクエストにクッキーを追加しなかった、または
  2. ブラウザはそれを拒否しました。

私の場合、それはサーバーでした。ローカル環境ではまだSSLを使用していませんでしたが、web.config次の行がありました。

<httpCookies requireSSL="True"/>

この場合の解決策は、SSLに切り替えるか、ローカル環境の値を「False」に設定したままにすることです。

12
Rod Borchevskyi

Rismの優れた答えに加えて、このエラーが発生する別の理由として、ブラウザまたはブラウザプラグインがCookieの設定をブロックしているが挙げられます。

8
Samuel Liew

Edgeブラウザでも同じ問題が発生しました。

ブラウザの設定を変更することで、この問題を修正しました。

指示に従って問題を修正します。

[設定]> [詳細設定を表示]> [Cookie]> [Cookieをブロックしない]に変更します。

ブラウザを閉じて確認します。

誰かを助けるかもしれないと思った。

3
Rajeev Kumar

フロントエンドの@ Html.AntiForgeryToken()でこの行を見逃していないかどうかを確認してください

1

この質問を見てみたいかもしれません。 MVC 4では、偽造防止Cookieトークンとフォームフィールドトークンが一致しません

これはタイムアウトの問題である可能性があります。基本的に、タイムアウトが発生すると、サイトが実行されているiisユーザーは適切なアクセス権を持っていないため、Cookieは保存されません。私にとっては、ユーザープロファイルを読み込むようにアプリケーションプールを変更しましたが、これで修正されたようです。