防止在后端ASP.NET Core 3中提交双重形式的提交。*

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了防止在后端ASP.NET Core 3中提交双重形式的提交。*相关的知识,希望对你有一定的参考价值。

我正在尝试在ASP.NET Web应用程序的后端实施某种形式的防止提交问题。我知道您可以在前端应用javascript / jquery技巧,但我真的很想一路在后端进行处理。

我正在使用.NET Core 3和PageModels。

我在这里查看了stackoverflow中的一些示例,但是似乎没有一个示例对我有用。我得到的最接近的是通过重写OnPageHandlerSelected,它在OnPost执行之前触发,并且正如文档中提到的在模型绑定之前触发。我正在使用Antiforgery令牌通过将最后一个令牌保存到会话中并将当前令牌与会话的最后一个令牌保存条目进行比较来检测重复的请求。

现在的问题是我尝试获取的会话字符串始终检索null。通过执行各种任务,我意识到我只能在OnPost方法完成执行后检索存储的会话值,而在此之前不能检索。这当然会造成问题,因为我的OnPost方法可能很长且需要一些时间。我知道我错过了一些东西,但我不确定是什么。

非常感谢任何帮助以及一些解释。谢谢您的时间。

这是演示此问题的PageModel代码:(请注意,我的启动文件包含AddSession和UseSession)

Test.cshtml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DoublePostApplication.Filters;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace DoublePostApplication


    public class TestModel : PageModel
    
        public string Amount  get; set; 

        public override void OnPageHandlerSelected(PageHandlerSelectedContext context)
        
            if (context.HttpContext.Request.Method == "POST")
            
                if (context.HttpContext.Request.Form.ContainsKey("__RequestVerificationToken"))
                
                    var currentToken = context.HttpContext.Request.Form["__RequestVerificationToken"].ToString();
                    var lastToken = context.HttpContext.Session.GetString("LastProcessedToken");

                    if (lastToken == currentToken)
                    
                        context.ModelState.AddModelError(string.Empty, "Double form submission detected.");
                    
                    else
                    
                        context.HttpContext.Session.SetString("LastProcessedToken", currentToken);
                    

                
            

            base.OnPageHandlerSelected(context);
        

        public ActionResult OnGet()
        
            return Page();
        

        public ActionResult OnPost()
        
            if (ModelState.IsValid)
            

             else
            
                return new BadRequestResult();
            

            return Page();
        
    


编辑

我设法获得会话值之前,通过添加以下代码行设法解决了我的问题

context.HttpContext.Session.LoadAsync().Wait();

以及我设置会话值后的以下代码行

context.HttpContext.Session.CommitAsync().Wait();

我相信正在发生的事情是我正在强迫会话以某种方式存储数据,但是我不确定当前正在发生什么。如果有人想解释为什么以上两行可以解决我的问题,我将很乐意接受他们的回答。请记住,该问题阻止了提交按钮的快速触发。提交表单后,上述代码可以防止重新提交。

答案

现在的问题是我试图获取的会话字符串,始终检索null。通过执行各种任务,我意识到我可以仅在我的OnPost方法完成后检索存储的会话值执行但不执行。

首先,请确保已经设置了LastProcessedToken的会话值。然后确保该会话尚未到期。当我尝试您的代码时,它运行良好。

我的startup.cs

public void ConfigureServices(IServiceCollection services)
    
        services.AddDistributedMemoryCache();

        services.AddSession(options =>
        
            // Set a short timeout for easy testing.
            options.IdleTimeout = TimeSpan.FromSeconds(100);
            options.Cookie.HttpOnly = true;
            // Make the session cookie essential
            options.Cookie.IsEssential = true;
        );

        services.AddRazorPages();
    

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    

        app.UseStaticFiles();
        app.UseSession();
        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        
            endpoints.MapRazorPages();
        );
    

以上是关于防止在后端ASP.NET Core 3中提交双重形式的提交。*的主要内容,如果未能解决你的问题,请参考以下文章

防止 Asp.NET 按钮提交表单

Google Chart和Chart.Js,在Asp .NET Core 2.2中将脚本端发送C#变量

如何在 ASP.NET Core 3.1 中启用多重身份验证?

ASP.Net Core DI 公司上下文提供者? [复制]

asp.net core 上传文件服务器拒绝是为啥?

在后端 ASP.NET MVC (MEF) 上发布/绑定多个表单