首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Ajax处理AntiForgeryToken发送

用Ajax处理AntiForgeryToken发送
EN

Stack Overflow用户
提问于 2014-03-06 10:45:01
回答 2查看 2.9K关注 0票数 2

你好,我在跟踪本教程:

我正在尝试发送Ajax请求,其中包括AntiforgeryToken。在这里,我的ajax请求:

代码语言:javascript
复制
$(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);
            }
        })
    })
});

在这里,我的控制器:

代码语言:javascript
复制
[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");
    }

但在本教程中,它们显示的功能如下:

代码语言:javascript
复制
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);
}

但是我不知道如何将这些代码放在控制器中,也不知道如何调用这个函数。有人能解释我怎么使用上面的代码吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-06 13:24:27

他们在教程的反CSRF和AJAX部分展示的是一种非标准的令牌验证方法。在本例中,您将不使用使用[ValidateAntiForgeryToken],而是手动运行验证。首先,在ajax调用中注入额外的标头:

代码语言:javascript
复制
        headers: {
            'RequestVerificationToken': '@TokenHeaderValue()'
        },

然后从操作中的标头读取并验证令牌:

代码语言:javascript
复制
[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]属性。

票数 5
EN

Stack Overflow用户

发布于 2019-12-30 08:00:38

对于那些有这个问题的人来说,接受的答案是好的,但是正如他提到的,您应该为更干净的代码创建动作筛选器--这就是我所做的

创建扩展类和方法

代码语言:javascript
复制
 public static class ExtentionUtilty
{
    public static string TokenHeaderValue()
    {
        string cookieToken, formToken;
        AntiForgery.GetTokens(null, out cookieToken, out formToken);
        return cookieToken + ":" + formToken;
    }
}

在cshtml和ajax调用中使用它。

代码语言:javascript
复制
$.ajax("api/values", {
    type: "post",
    contentType: "application/json",
    data: {  }, // JSON data goes here
    dataType: "json",
    headers: {
        'RequestVerificationToken': '@ExtentionUtilty.TokenHeaderValue()'
    } 
});

创建一个ActionFilter

代码语言:javascript
复制
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();
        }
    }
}

只需像这样使用它:

代码语言:javascript
复制
    [HttpPost]
    [ValidateHeaderAntiForgery]
    [Authorize(Roles = "Admin")]
    public ActionResult ActiveBoomSar(int id, modelDto model){}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22222078

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档