私は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 });
}
}
偽造防止トークンでファイルを送信するにはどうすればよいですか?
ファイルアップロードはトークンチェックなしで動作しますか? – Jasen
はい、ただし、ビューからAntiForgeryTokenを削除した場合のみ –
以下のスタックオーバーフロースレッドを確認してください [jQueryのAjax呼び出しとHtml.AntiForgeryToken()](http://stackoverflow.com/questions/32779931/how-to -send-antiforgerytoken-csrf-with-formdata-via-jquery-ajax) –