带有asp .net核心的防伪令牌jquery ajax
Posted
技术标签:
【中文标题】带有asp .net核心的防伪令牌jquery ajax【英文标题】:Anti forgery token jquery ajax with asp .net core 【发布时间】:2020-06-22 02:26:59 【问题描述】:我正在使用 jQuery 执行 ajax 请求,将其发送到 asp .net 核心控制器。我将请求与防伪令牌一起发送,如下所示:
$('#btnSyncDictionary').click(function (event)
$.ajax(
type: "POST",
url: "HealthPanel/SyncDictionary",
headers: "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val()
);
event.stopImmediatePropagation();
event.stopPropagation();
);
问题是它只适用于第一个 ajax 调用。随后的 ajax 调用未能通过 asp .net 核心控制器的防伪验证。
为什么会这样?我想我可能需要在每次请求后更新令牌。
【问题讨论】:
您能否分享有关您的视图和 SyncDictionary 操作的更多详细信息? 嗨@Alecu,你还有问题吗?你能分享更多可以重现你的问题的细节吗? 【参考方案1】:TestMiddleware.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
namespace Test.Middleware
public class TestMiddleware
private readonly RequestDelegate _next;
public TestMiddleware(RequestDelegate next)
_next = next;
public async Task InvokeAsync(HttpContext httpContext, AppDbContext dataContext, UserManager<User> userManager, IAntiforgery antiforgery)
SetAntiForgeryTokenCookie();
// Move forward into the pipeline
await _next(httpContext);
private void SetAntiForgeryTokenCookie(HttpContext httpContext, IAntiforgery antiforgery)
var tokens = antiforgery.GetAndStoreTokens(httpContext);
httpContext.Response.Cookies.Append("CSRF-TOKEN", tokens.RequestToken, new CookieOptions() HttpOnly = false );
public static class TestMiddlewareExtensions
public static IApplicationBuilder UseTestMiddleware(this IApplicationBuilder builder)
return builder.UseMiddleware<TestMiddleware>();
#endregion
Startup.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Test.Middleware;
namespace Test
public class Startup
public Startup(IConfiguration configuration)
Configuration = configuration;
public IConfiguration Configuration get;
public void ConfigureServices(IServiceCollection services)
services.AddControllersWithViews();
services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("Database"), b => b.MigrationsAssembly("Test")));
services.AddIdentity<User, Role>()
.AddEntityFrameworkStores<AppDbContext>()
.AddDefaultTokenProviders();
services.Configure<IdentityOptions>(options =>
// Password settings
options.Password.RequireDigit = true;
options.Password.RequiredLength = 8;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = true;
options.Password.RequireLowercase = false;
options.Password.RequiredUniqueChars = 6;
// Lockout settings
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
options.Lockout.MaxFailedAccessAttempts = 10;
options.Lockout.AllowedForNewUsers = true;
// User settings
options.User.RequireUniqueEmail = true;
);
services.ConfigureApplicationCookie(options =>
// Cookie settings
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(480);
options.LoginPath = "/Account/Login";
options.AccessDeniedPath = "/Account/AccessDenied";
options.SlidingExpiration = true;
);
services.AddAntiforgery(options =>
// Antiforgety settings
options.HeaderName = "X-CSRF-TOKEN";
);
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IAntiforgery antiforgery)
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
else
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseTestMiddleware();
app.UseEndpoints(endpoints =>
endpoints.MapControllerRoute(
name: "default",
pattern: "controller=Home/action=Index/id?");
);
script.js
self.saveSurvey = function (userId)
var csrfToken = self.getCookie("CSRF-TOKEN");
var ajaxUrl = "Account/Save",
ajaxData =
UserId: userId
;
$.ajax(
type: "POST",
url: ajaxUrl,
data: JSON.stringify(ajaxData),
cache: false,
contentType: "application/json; charset=utf-8",
dataType: 'json',
headers:
"X-CSRF-TOKEN": csrfToken
,
success: function (viewModel)
console.log("Eureka!")
,
error: function (error)
console.log("Not Eureka!")
);
;
【讨论】:
以上是关于带有asp .net核心的防伪令牌jquery ajax的主要内容,如果未能解决你的问题,请参考以下文章
使用防伪令牌将 JSON 模型发布到 ASP.Net MVC3
如何使用带有 OpenId Connect 的刷新令牌在 asp.net 核心中处理过期的访问令牌