10

【ASP.NET Core】解决“The required antiforgery cookie "xxx" is not pres...

 3 years ago
source link: https://www.cnblogs.com/tcjiaan/p/8482734.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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

当你在页面上用 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。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK