[英]Anti forgery token jquery ajax with asp .net core
我正在使用 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 核心控制器的防偽驗證。
為什么會發生這種情況? 我想我可能需要在每次請求后更新令牌。
測試中間件.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
}
啟動文件
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?}");
});
}
}
}
腳本.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!")
}
});
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.