【ASP.NET Core】解决“The required antiforgery cookie "xxx" is not present”的错误

作者: 段干杯

更新时间:2022-03-26 13:11:17

2794 阅读

当你在页面上用 form post 内容时,可能会遇到以下异常:

The required antiforgery cookie "????????" is not present.

咱们来重现一下错误。新建一个 ASP.NET Core 项目,模板选【空】就行了,这是老周最喜欢的项目模板,空 == 自由。

在项目下建一个目录,叫 Pages,用来放 Razor 页面;然后建一个 Index.cshtml 页。

之所以叫 Index.cshtml,是因为 Index 是默认页的名字,这样输入根 URL 就能访问。如果不叫 Index 呢,比如这样。

此时你可以在根 URL 后面加上 demo 来访问,如果想在根目录下访问,也可以在 Startup.ConfigureServices 方法中配置页面路由。

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().AddRazorPagesOptions(o =>
            {
                o.Conventions.AddPageRoute("/Demo", "");
            });
        }

写路径时一定要注意大小写,在浏览器中输入时不需要注意,但在编程时要注意。AddPageRoute 方法是个扩展方法,pagename 参数表明你要的目标页面,比如我要到达 /Demo 页,route 参数设置路由,空字符串表示根路径。即我在浏览器中输入 http://somehost/,就能定位到 http://somehost/Demo 页。

如果 pagename 为 /users/newone,route 参数为 new,那么,你访问 http://somehost/new 就会指向 http://somehost/users/newone。

你得注意的是,这个 razor page 的路由规则只用于 Web Pages,不是 MVC 的路由规则,这个设置对 MVC 是不起作用的,MVC 可以用类似 {controller]/{action}/{id} 的路由,这个相信你很熟练了(当然,前提是你写过 MVC 应用)。

 

顺便在 Configure 方法中加上 use 代码,不管是 Web Pages 还是 MVC 都要加上。

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseMvc();
        }

 

现在可以弄一下页面了。打开页面,你发现找不到对应的 PageModel 类,这里老周推荐用 _ViewImports 文件来处理。

在 Pages 目录下添加一个视图导入文件。

然后,引入要用的命名空间。

@using WebSample09
@using WebSample09.Pages

但是这不够完善,还要加一行。

@namespace WebSample09.Pages

@namespace 指令用来设定 Razor 页所生成代码的命名空间,这样就可以确保页面与 PageModel 类型处于同一个命名空间,可以避免将来发生各种错误。

 

保存并关闭导入页,回到刚刚添加的页面。

@page
@model DemoModel

<!doctype html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
    <title>示例</title>
</head>
<body>
    <form method="post">
        <label for="parm">请随便输入:</label>
        <input type="text" name="parm" />
        <button type="submit">提交</button>
    </form>
</body>
</html>

打开对应的 PageModel 类代码,写一个 OnPost 方法。

public void OnPost(string parm)
        {
            ViewData["data"] = $"你输入的的值是:{parm}";
        }

在 POST 之后,通过 parm 参数(与页面 form 元素中字段命名相同,会自动赋值)获取输入的内容,存到 ViewData 中,为了在页面上显示,我们回到刚才的页面,加一个 p 元素,用来显示输入内容。

  <p>@ViewData["data"]?.ToString()</p>

好,现在可以测试了。

 

运行,进入页面。

 

输入内容,点按钮提交,会收到 400 错误。

 

 

此时 Console Log 记录下一个异常。

即我们开头所说的那个错误,这个验证主要为了安全考虑,防止别人盗了你的数据然后跨域欺骗服务器。

 

那么,咋解决呢?说出来你可能不信,很简单。

打开刚刚咱们加到项目中的那个视图导入页,然后添加一个 form 元素的 Tag Helper 就行了。

@addTagHelper  Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers

格式是这样的,很常规,就是 .net 类型的表示方法,用英文的逗号隔开,前面是类型(包括命名空间),后面是程序集名称。

 添加标记帮助器前,代码编辑器中是显示为这种颜色的。

添加标记帮助器后,显示为这种颜色。

 

这时候就可以了。

 

咱们不妨对比一下,看看应用标记 Helper 前后输出到客户端的 HTML 有啥不同。

在未使用标记帮助器前,提交时会出现 400 错误,生成的 HTML 如下:

<form method="post">
        <label for="parm">请随便输入:</label>
        <input name="parm" type="text">
        <button type="submit">提交</button>
</form>

基本是原文输出。

 

应用 form 元素帮助器后,生成的 HTML 如下:

<form method="post">
        <label for="parm">请随便输入:</label>
        <input name="parm" type="text">
        <button type="submit">提交</button>
    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8DEAGDEorWJFuzYOfcGEJpSWrKHd5Qrw4jdARVRF3SwAS-TChnUQHEsFWxtXTk7IDCmpRAB241ucR6kdZA-sRBHnsyOe01ymGLs-DONlZYmB-MzvmXgJmKcn2ZrYMN-Br8fj25nX_zvuwzhyNQ42Das" />
</
form>

多了一个名为 __RequestVerificationToken 的隐藏元素,标识当前请求会话,防止被人冒用。

 

顺便补充一下,如果你想导入各种 Tag Helper ,可以把类型名改为 * (星号,通配符)。

@addTagHelper  *, Microsoft.AspNetCore.Mvc.TagHelpers

 

好了,今天的内容扯到这儿了,88。

 

版权声明:本文著作权归作者【段干杯 】所有,不代表本网站立场。

侵权请联系:root_email@163.com

相关推荐