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

Jos*_*e A 5 javascript asp.net-mvc dropzone.js

我现在正试图弄清楚如何使用Dropzone.js和vanilla 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
        });

    });
Run Code Online (Sandbox Code Playgroud)

我尝试将令牌添加到Dropzone的发送事件无效,即使在标题处也是如此.有关如何实现这一目标的任何建议?

Jos*_*e A 6

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

从这里获取这个想法: http://johan.driessen.se/posts/Updated-Anti-XSRF-Validation-for-ASP.NET-MVC-4-RC

我设法通过 dropzone 的标头发送令牌:

代码最终是这样的:

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

我将“标头”添加到 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"]);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后应用到你的控制器:

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

        return Json("Success");
}
Run Code Online (Sandbox Code Playgroud)


Dav*_*and 6

我想你一开始就差点把它钉在那里,何塞。您犯的一个小错误是在事件处理函数中缺少一个参数。

Dropzone 文档

在发送每个文件之前调用。获取 xhr 对象和 formData 对象作为第二个和第三个参数,因此您可以修改它们(例如添加 CSRF 令牌)或添加其他数据。

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

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

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

  • 对我来说,使用 formData.append("__RequestAntiForgeryToken", tokenElement) 也有效。 (2认同)
  • 对我来说,它仅适用于“formData.append(k,v)”,不适用于“formData[k]= v”,并且它必须是“__RequestVerificationToken”而不是“__RequestAntiForgeryToken”(asp.net core 3) (2认同)