2017-01-12 14 views
1

私はajax呼び出しでファイルをアップロードしようとしており、反偽造トークンを検証しようとしています。私は周りを見て、コントローラ上の反偽造トークンを検証する方法を構築しました。しかし、私がビューに@Html.AntiForgeryTokenを持っているときはいつでも、私のファイルにはデータが取り込まれません。反偽造トークンを検証しても。要求と一緒に送信されているようには見えませんが、私は理由が分かりません。Ajaxファイルのアップロードで偽造トークンを送信する方法は?

ajaxSendOverride:

$(document).ready(function() { 

    var securityToken = $('[name=__RequestVerificationToken]').val(); 

    $(document).ajaxSend(function (event, request, opt) { 
     if (opt.hasContent && securityToken) { // handle all verbs with content 

      var tokenParam = "__RequestVerificationToken=" + encodeURIComponent(securityToken); 

      opt.data = opt.data ? [opt.data, tokenParam].join("&") : tokenParam; 

      // ensure Content-Type header is present! 
      if (opt.contentType !== false || typeof event.contentType !== 'undefined') { 
       request.setRequestHeader("Content-Type", opt.contentType); 
      } 
     } 
    }); 
}); 

アヤックス:

$(document).on("submit", "[data-upload-contract-form]", function (e) { 
     e.preventDefault(); 
     var formData = new FormData($('[data-upload-contract-form]')[0]); 
     if ($('[data-upload-file]').val() != "") { 
      $.ajax({ 
       url: $(this).attr('action'), 
       data: formData, 
       type: 'POST', 
       processData: false, 
       contentType: false, 
       headers: { 
        '__RequestVerificationToken': $('[name=__RequestVerificationToken]').val() 
       }, 
       success: function (data) { 
        if (data.Success === true) { 
         $('[data-contract-error-message]').text(); 
         ReturnDataTableForUploadFile($('[data-upload-file-supplier-contract-id]').val()); 
         table.ajax.reload(); 
        } 
        else { 
         $('[data-contract-error-message]').show(); 
         $('[data-contract-error-message]').text(data.ResponseText); 
        } 
       } 
      }) 
      .fail(function() { 
       $('[data-contract-error-message]').show(); 
       $('[data-contract-error-message]').text("Something went wrong uploading your file, please try again."); 
      }); 
     } 
     else { 
      $('[data-contract-error-message]').show(); 
      $('[data-contract-error-message]').text("No contract to upload"); 
     } 
    }); 

検証:

public sealed class AuthorizeAntiForgeryToken : System.Web.Mvc.FilterAttribute, System.Web.Mvc.IAuthorizationFilter 
    { 
     public void OnAuthorization(AuthorizationContext filterContext) 
     { 
      var httpContext = filterContext.HttpContext; 
      var cookie = httpContext.Request.Cookies[AntiForgeryConfig.CookieName]; 
      AntiForgery.Validate(cookie != null ? cookie.Value : null, 
           httpContext.Request.Headers["__RequestVerificationToken"]); 
     } 
    } 

コントローラー:

public async Task<JsonResult> UploadContract(UploadContract model) 
     { 
      if (ModelState.IsValid) 
      { 
       try 
       { 
        foreach (var item in model.Contracts) 
        { 
         string filePath = WebConfigurationManager.AppSettings["SupplierContractPath"] + GetSelectedClientId() + "\\" + item.FileName; 

         _supplierFileManager.UploadFile(item, filePath); 

         await _supplierFileManager.SaveContractToDatabase(model.SupplierContractID, item.FileName); 
        } 
        return Json(new { Success = true }); 
       } 
       catch (Exception e) 
       { 
        return Json(new { Success = false, ResponseText = e.Message }); 
       } 
      } 
      else 
      { 
       string errorMessage = ""; 
       foreach (var item in ModelState.Values.SelectMany(r => r.Errors)) 
       { 
        errorMessage += "<p>" + item.ErrorMessage + "</p>"; 
       } 
       return Json(new { Success = false, ResponseText = errorMessage }); 
      } 
     } 

偽造防止トークンでファイルを送信するにはどうすればよいですか?

+0

ファイルアップロードはトークンチェックなしで動作しますか? – Jasen

+0

はい、ただし、ビューからAntiForgeryTokenを削除した場合のみ –

+0

以下のスタックオーバーフロースレッドを確認してください [jQueryのAjax呼び出しとHtml.AntiForgeryToken()](http://stackoverflow.com/questions/32779931/how-to -send-antiforgerytoken-csrf-with-formdata-via-jquery-ajax) –

答えて

1

私は今日この問題に遭遇し、答えなしでこの質問に遭遇しました。他の回答へのリンクはうまくいかなかったが、しばらくして解決策を見つけた。

偽造防止トークンは、ヘッダーではなくフォームフィールド内にある必要があります。また、フォームデータ内のの最初のフィールドである必要があります。だから、それを解決するためには、実行します。正常に動作します

$(document).on("submit", "[data-upload-contract-form]", function (e) { 
     e.preventDefault(); 
     var formData = new FormData(); 
     formData.append('__RequestVerificationToken', $('[name=__RequestVerificationToken]').val()); 
     formData.append('file', $('[data-upload-contract-form]')[0]); 
     if ($('[data-upload-file]').val() != "") { 
      $.ajax({ 
       url: $(this).attr('action'), 
       data: formData, 
       type: 'POST', 
       processData: false, 
       contentType: false, 
       success: function (data) { 
        if (data.Success === true) { 
         $('[data-contract-error-message]').text(); 
         ReturnDataTableForUploadFile($('[data-upload-file-supplier-contract-id]').val()); 
         table.ajax.reload(); 
        } 
        else { 
         $('[data-contract-error-message]').show(); 
         $('[data-contract-error-message]').text(data.ResponseText); 
        } 
       } 
      }) 
      .fail(function() { 
       $('[data-contract-error-message]').show(); 
       $('[data-contract-error-message]').text("Something went wrong uploading your file, please try again."); 
      }); 
     } 
     else { 
      $('[data-contract-error-message]').show(); 
      $('[data-contract-error-message]').text("No contract to upload"); 
     } 
    }); 

私自身の機能を(jQueryのを使用して):(それは完全ではないですが、少なくともそれはファイルを受け取ったバック報告;))

<script type="text/javascript"> 
    function uploadFileThroughForm(messageId) { 
     var form = $('#addAttachmentForm'); 
     if (form.valid()) { 
      var files = $('#filenameToUpload').prop('files'); 
      if (files.length > 0) { 
       if (window.FormData !== undefined) { 
        var formData = new FormData(); 
        formData.append("__RequestVerificationToken", $('#addAttachmentForm input[name=__RequestVerificationToken]').val()); 
        formData.append("file", files[0]); 
        $.ajax({ 
         type: "POST", 
         url: '@ApplicationAdapter.GetVirtualRoot()Attachment/Add/' + messageId, 
         contentType: false, 
         processData: false, 
         data: formData, 
         success: function(result) { 
          alert(result.responseMessage); 
         }, 
         error: function(xhr) { 
          alert(xhr.responseText); 
         } 
        }); 
       } else { 
        alert("This browser doesn't support HTML5 file uploads!"); 
       } 
      } 
     } 
    } 
</script> 

あなたがこの質問をしてからしばらくお待ちいただいていますが、これが助けてくれることを願っています!

関連する問題