【问题标题】:How do I use AntiforgeryToken with dropzone.js and MVC 5 with Vanilla JS?如何将 AntiforgeryToken 与 dropzone.js 和 MVC 5 与 Vanilla JS 一起使用?
【发布时间】:2015-08-29 15:54:36
【问题描述】:

我目前正试图弄清楚如何使用 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
        });

    });

我已经尝试在 Dropzone 的发送事件中添加令牌,但在标题中也无济于事。关于如何实现这一目标的任何建议?

【问题讨论】:

    标签: javascript asp.net-mvc dropzone.js


    【解决方案1】:

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

    来自Dropzone documentation

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

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

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

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

    【讨论】:

    • 对我来说使用formData.append("__RequestAntiForgeryToken", tokenElement)也有效。
    • 对我来说,它只适用于formData.append(k,v) 而不是formData[k]= v,它必须是__RequestVerificationToken 而不是__RequestAntiForgeryToken(asp.net core 3)
    【解决方案2】:

    我最终实现这一目标的方式是通过 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 }
            });
    

    我在 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");
    }
    

    【讨论】:

    • 老兄,这是金!真是难得一见的宝物。干得好。
    • 我发现 dropzone 在标头有效负载中将 __RequestVerificationToken 设置为小写,而 MVC 失败。很奇怪……
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多