你好,我在跟踪本教程:
我正在尝试发送Ajax请求,其中包括AntiforgeryToken。在这里,我的ajax请求:
$(document).ready(function () {
@functions{
public string TokenHeaderValue()
{
string cookieToken, formToken;
AntiForgery.GetTokens(null, out cookieToken, out formToken);
return cookieToken + ":" + formToken;
}
}
$('.z').on('click', function (event) {
event.preventDefault();
$.ajax({
url: "/DeviceUsage/Return",
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: 'html',
headers: {
'RequestVerificationToken': '@TokenHeaderValue()'
},
data: JSON.stringify({ dev: { DeviceInstanceId: $('#DeviceInstanceId').val(), UserId: "1", StorageId: $('#StorageId').val() } }),
error: function (data) {
alert("wystąpił nieokreślony błąd " + data);
},
success: function (data) {
$('.modal-body').html(data);
}
})
})
});在这里,我的控制器:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Return(DeviceUsage dev)
{
if(dev.StorageId==3)
{
ModelState.AddModelError("", "Nie można oddać na własne biurko");
ViewBag.StorageId = new SelectList(unitOfWork.storageRepository.Get(), "Id", "Name", dev.StorageId);
return PartialView(dev);
}
dev.UserId = 1;
unitOfWork.deviceUsageRepository.Update(dev);
unitOfWork.Save();
return RedirectToAction("MyDevices");
}但在本教程中,它们显示的功能如下:
void ValidateRequestHeader(HttpRequestMessage request)
{
string cookieToken = "";
string formToken = "";
IEnumerable<string> tokenHeaders;
if (request.Headers.TryGetValues("RequestVerificationToken", out tokenHeaders))
{
string[] tokens = tokenHeaders.First().Split(':');
if (tokens.Length == 2)
{
cookieToken = tokens[0].Trim();
formToken = tokens[1].Trim();
}
}
AntiForgery.Validate(cookieToken, formToken);
}但是我不知道如何将这些代码放在控制器中,也不知道如何调用这个函数。有人能解释我怎么使用上面的代码吗?
发布于 2014-03-06 13:24:27
他们在教程的反CSRF和AJAX部分展示的是一种非标准的令牌验证方法。在本例中,您将不使用使用[ValidateAntiForgeryToken],而是手动运行验证。首先,在ajax调用中注入额外的标头:
headers: {
'RequestVerificationToken': '@TokenHeaderValue()'
},然后从操作中的标头读取并验证令牌:
[HttpPost]
public ActionResult Return(DeviceUsage dev)
{
ValidateRequestHeader(Request);
//process action
}
void ValidateRequestHeader(HttpRequestBase request)
{
string cookieToken = "";
string formToken = "";
if (request.Headers["RequestVerificationToken"] != null)
{
string[] tokens = request.Headers["RequestVerificationToken"].Split(':');
if (tokens.Length == 2)
{
cookieToken = tokens[0].Trim();
formToken = tokens[1].Trim();
}
}
AntiForgery.Validate(cookieToken, formToken);
}注意,ValidateRequestHeader()读取jQuery调用前面设置的头。此外,我还稍微修改了方法,以接受HttpRequestBase。
提示:要避免将ValidateRequestHeader()添加到每个响应ajax调用的控制器中,请将其添加到基本控制器(如果有),并从基中派生出所有控制器。或者更好地使用创建您自己的[ValidateAntiForgeryAjaxToken]属性。
发布于 2019-12-30 08:00:38
对于那些有这个问题的人来说,接受的答案是好的,但是正如他提到的,您应该为更干净的代码创建动作筛选器--这就是我所做的
创建扩展类和方法
public static class ExtentionUtilty
{
public static string TokenHeaderValue()
{
string cookieToken, formToken;
AntiForgery.GetTokens(null, out cookieToken, out formToken);
return cookieToken + ":" + formToken;
}
}在cshtml和ajax调用中使用它。
$.ajax("api/values", {
type: "post",
contentType: "application/json",
data: { }, // JSON data goes here
dataType: "json",
headers: {
'RequestVerificationToken': '@ExtentionUtilty.TokenHeaderValue()'
}
});创建一个ActionFilter
public class ValidateHeaderAntiForgeryAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
string cookieToken = "";
string formToken = "";
if (filterContext.HttpContext.Request.Headers["RequestVerificationToken"] != null)
{
string[] tokens = filterContext.HttpContext.Request.Headers["RequestVerificationToken"].Split(':');
if (tokens.Length == 2)
{
cookieToken = tokens[0].Trim();
formToken = tokens[1].Trim();
}
}
try
{
AntiForgery.Validate(cookieToken, formToken);
base.OnActionExecuting(filterContext);
}
catch
{
filterContext.Result = new HttpNotFoundResult();
}
}
}只需像这样使用它:
[HttpPost]
[ValidateHeaderAntiForgery]
[Authorize(Roles = "Admin")]
public ActionResult ActiveBoomSar(int id, modelDto model){}https://stackoverflow.com/questions/22222078
复制相似问题