如何将 AntiforgeryToken 与 dropzone.js 一起使用,将 MVC 5 与 Vanilla JS 一起使用?

How do I use AntiforgeryToken with dropzone.js and MVC 5 with Vanilla JS?

我现在正试图弄清楚如何使用 Dropzone.js 和香草 javascript(没有 jQuery)发送防伪令牌。

这是我目前的初始化代码:

$(document).ready(function (e) {
        var myDropzone = new Dropzone("#myDropzone", { url: "/Media/AjaxUpload", maxFilesize: 10, addRemoveLinks: true, maxFiles: 1 });
        myDropzone.on("success", function (response) {
            //Do some personal stuff.
        });
        myDropzone.on("sending", function (xhr, formData) {
            formData["__RequestAntiForgeryToken"] = document.getElementsByName("__RequestVerificationToken")[1].value
        });

    });

我曾尝试在 Dropzone 的发送事件中附加令牌,但没有成功,即使是 header。关于如何实现这一目标的任何建议?

我最终实现这一目标的方法是通过 Whosebug 上的许多建议。我在 MVC 上创建了一个特殊的过滤器,并通过 headers 传递了令牌。像这样:

借鉴这里的想法: http://johan.driessen.se/posts/Updated-Anti-XSRF-Validation-for-ASP.NET-MVC-4-RC

我设法通过 dropzone 的 header:

发送了令牌

代码最终是这样的:

var myDropzone = new Dropzone("#myDropzone", {
            url: "/Media/AjaxUpload", maxFilesize: 10, addRemoveLinks: true, maxFiles: 1,
            headers: { "__RequestVerificationToken": document.getElementsByName("__RequestVerificationToken")[1].value }
        });

我将 "headers" 添加到 Dropzone 实例化,并将过滤器添加到 MVC:

  [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple= false, Inherited = false)]
public sealed class ValidateJsonAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }

        var httpContext = filterContext.HttpContext;
        var cookie = httpContext.Request.Cookies[AntiForgeryConfig.CookieName];
        AntiForgery.Validate(cookie != null ? cookie.Value : null,
                             httpContext.Request.Headers["__RequestVerificationToken"]);
    }
}

然后应用到您的控制器:

 [ValidateJsonAntiForgeryToken]
    public JsonResult AjaxUpload(HttpPostedFileBase file)
    {
        //Do Logic here!

        return Json("Success");
}

Jose,我想你几乎一开始就成功了。您犯的小错误是在事件处理函数中缺少一个参数。

来自Dropzone documentation

Called just before each file is sent. Gets the xhr object and the formData objects as second and third parameters, so you can modify them (for example to add a CSRF token) or add additional data.

事件参数实际上是 file, xhr, formData,如果您包括所有三个,那么您就可以成功地操作表单。这样做的好处是不需要创建自定义属性,只需使用 ValidateAntiForgeryToken 属性即可。

myDropzone.on("sending", function (file, xhr, formData) {
    formData["__RequestAntiForgeryToken"] = document.getElementsByName("__RequestVerificationToken")[1].value;
});

我已经使用与您的稍有不同的实现方式对此进行了测试,并且效果很好。