Добавить токен защиты от подделки в XMLHttpRequest - PullRequest
0 голосов
/ 31 января 2019

В значительной степени то, что говорит название.Вот javascript ... Работает нормально, когда не проверяет токен.Не появляется при проверке, когда я получаю ошибку The required anti-forgery form field "__RequestVerificationToken" is not present..

var downloadEmailSignature = function (control) {
    if (control) {
        let form = $(control).closest('form');
        let token = $(form).find('input[name="__RequestVerificationToken"]').val();

        if (form) {
            let request = new XMLHttpRequest();
            request.open("POST", "Forms/DownloadEmailSignature");
            request.responseType = "blob";
            request.setRequestHeader('RequestVerificationToken', token);
            request.data = form.serialize();
            request.onload = function () {
                if (window.clientData.browser.name === "Internet Explorer") {
                    window.navigator.msSaveBlob(this.response, "EmailSignature.hta");
                }
                else{
                    let url = window.URL.createObjectURL(this.response);
                    let a = document.createElement("a");
                    document.body.appendChild(a);
                    a.href = url;
                    a.download = this.response.name || "download-" + $.now();
                    a.click();
                }
            };
            console.dir(request);
            request.send();
        }
    }
};

и код позади ...

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult DownloadEmailSignature(string emailSignature)
    {
        var hta = (MediaItem)SitecoreContext.GetItem<Item>(new Guid("{EE806F14-5BD3-491C-9169-DA701357FB45}"));

        using (var reader = new StreamReader(MediaManager.GetMedia(hta).GetStream().Stream))
        {
            var htaText = reader.ReadToEnd();

            htaText = htaText.Replace("*CARDSTRING*", emailSignature);

            var stream = new MemoryStream(htaText.ToASCIIByteArray());

            return new FileStreamResult(stream, "application/hta");
        }
    }

И, наконец, представление ...

<form id="download-email-signature" method="POST" enctype="multipart/form-data">
    @Html.HiddenFor(m => m.EmailSignatureMarkup)
    @Html.AntiForgeryToken()                                          
    @Html.FormIdentifier("FormsController", "DownloadEmailSignature")
    <a href="#" id="download-installer" onclick="downloadEmailSignature(this); return false;" class="btn-primary" style="margin-bottom:10px;margin-top:-10px;text-align:center;">Download installer</a>
</form>

Ответы [ 2 ]

0 голосов
/ 31 января 2019

Согласно ответу здесь:

Цель, объяснение и пример ValidateAntiForgeryToken

Поддержка защиты от подделки MVC записывает уникальное значение только для HTTPcookie, а затем то же значение записывается в форму.Когда страница отправляется, возникает ошибка, если значение файла cookie не соответствует значению формы.

Что означает, что файл cookie ДОЛЖЕН возвращаться на сервер.Это должно работать нормально, если вы не используете IE9 (который, как известно, проблематичен с этой проблемой).

Я рекомендую включить request.withCredentials = true;, чтобы устранить любые странные проблемы, связанные с COR.

Если задействован прокси-сервер, возможно, файл cookie также удаляется на обратном пути к серверу.

0 голосов
/ 31 января 2019

Если вы можете заменить XMLHttpRequest на $.ajax (так как JQuery уже загружен), следующий сегмент должен работать.

let form = $(control).closest('form');
let token = $(form).find('input[name="__RequestVerificationToken"]').val();

$.ajax({
    url: '/Home/DownloadEmailSignature',
    type: 'POST',
    data: {
        __RequestVerificationToken: token,
        emailSignature: 'emailSignature value'
    },
    success: function (result) {
        alert(result);
        //your code ....
    }
});
...