雷达智富

首页 > 内容 > 程序笔记 > 正文

程序笔记

.NET Core Razor Page ajax请求返回400 Bad request

2024-10-14 88

Razor页面被设计为默认启动防跨站请求伪造攻击的,防伪令牌生成和验证被自动包含在Razor页面中。

打开页面可以看到表单里有一个隐藏的input

<input name="__RequestVerificationToken" type="hidden" value="CfDJ8JOahXSw05tKp2_4iLUJCzMYUFLeMGC-YtsK1ulbUapsD3ee0F0P7aZO1t7CmRHpOugTxUyhtcsIGtcdShW0k7cfA-dTHjTw2TPRDGU1PGnxGxIl39RWCeMGvswAhToLPfBBmkUUTkS3x4eFFTbIO_Y">

那么在ajax请求的时候应该把这个input的一起提交,示例如下:

<script>

    $('#ajax').click(function () {

        $.ajax({

            type: "POST",

            url: "",

            beforeSend: function (xhr) { },

            data: { __RequestVerificationToken: $('input:hidden[name="__RequestVerificationToken"]').val() },

            success: function (response) { console.log(response); }

        });

    });

</script>

这样就能Post成功了。

可以全局禁用掉防伪令牌验证,在Startup.cs中修改如下:

public void ConfigureServices(IServiceCollection services)

{

    services.AddMvc().AddRazorPagesOptions(o=>

    {

        o.Conventions.ConfigureFilter(new IgnoreAntiforgeryTokenAttribute());

    }).InitializeTagHelper<FormTagHelper>((helper, context) => helper.Antiforgery = false);

}

这样请求的时候就不会检查防伪令牌了,并且form表单里也不会出现隐藏的input了。

也可以对部分页面禁用防伪令牌验证,两种方法如下:

1 在Startup类的ConfigureServices方法进行配置,不过要提供页面的路径:

public void ConfigureServices(IServiceCollection services)

{

    //或者services.AddMvc().AddRazorPagesOptions...

    services.AddRazorPages().AddRazorPagesOptions(opotions =>

    {

        opotions.Conventions.AddPageApplicationModelConvention("/Index1",

            pageApplicationModel => pageApplicationModel.Filters.Add(new Microsoft.AspNetCore.Mvc.IgnoreAntiforgeryTokenAttribute()));

    });

}

在此处,我们禁用了Index页面的防伪令牌验证。

2 在PageModel上面使用标记:

[IgnoreAntiforgeryToken(Order = 1001)]

public class IndexModel : PageModel

{

    public void OnPost()

    {

    }

}

ValidateAntiForgeryToken标记默认的Order属性为1000,因此IgnoreAntiforgeryToken属性需要一个更高的序号。

改完之后再通过ajax请求的时候也不会返回400错误了,但是我们发现页面上还是会自动加入这个隐藏的input,如何解决呢?

禁用防伪令牌验证不会阻止生成隐藏字段或cookie,所以需要禁用FormTagHelper生成令牌。

<form method="post" asp-antiforgery="false"></form>

这样就不会有这个隐藏的input了。

更新于:3个月前
赞一波!2

文章评论

评论问答