问题
I have run into this problem for which I have been scratching my head for hours now.
The problem: The Session State that I create on Login
gets mysteriously cleared or lost after calling an API
controller which is also in .NET CORE 2.1. This happens when I call a API
method that looks like:
[Authorize(Policy = "AdminViewPolicy")]
[HttpGet("GetAllUsersId")]
public IActionResult GetAllUsersId()
{
var user = _userService.GetAllUsersId();
return Ok(new
{
data = user
});
}
The roles and other aspects of this method are working correctly. This is how I call this action method:
$.ajax({
url: "https://www.someworkingwebsite.com/api/Users/GetAllUsersId",
type: "GET",
async: false,
dataType: "json",
contentType: "application/json",
data: {},
credentials: 'include',
xhrFields: {
withCredentials: true
},
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", window.localStorage.getItem("authToken"));
},
success: function (data) {
console.log(data);
var html = [];
for (var i in data["data"]) {
var id = data["data"][i]["fullName"] + "###" + data["data"][i]["uuid"] + "###" + data["data"][i]["id"];
//var id = data["data"][i]["uuid"] + "###" + data["data"][i]["id"];
html.push(id);
}
/*initiate the autocomplete function on the "searchInput" element, and pass along the countries array as possible autocomplete values:*/
autocomplete(document.getElementById("searchInput"), html);
},
error: function () {
console.log("Error" + data);
},
});
My Startup.cs configuration for API
project looks like:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors();
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(30);
});
services.AddMvc(options =>
{
options.Filters.Add(typeof(ValidateModelAttribute));
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddHttpContextAccessor();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
//Other code omitted for brevity
app.UseForwardedHeaders();
// global cors policy
app.UseCors(x => x
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
app.UseAuthentication();
app.UseSession();
}
My client side filter for checking Session
looks like:
public override void OnActionExecuting(ActionExecutingContext context)
{
if (Context.Current.Session == null || !Context.Current.Session.TryGetValue("UserID", out byte[] val))
{
context.Result =
new RedirectToRouteResult(new RouteValueDictionary(new
{
controller = "Pages",
action = "SessionTimeout"
}));
}
base.OnActionExecuting(context);
}
The part where it gets tricky. When I call the AJAX function from my View
, the AJAX successfully calls the API
method and gets the required data needed, but also with that the AJAX call clears my session off somehow because as soon I navigate to some other page or make form submission, the SessionTimeout
attribute shown above gets called and I am kicked out of the system.
I have checked all Console logs, Network requests, Application storage on my web browser and I could not find the culprit. I also checked the logic in my both the API and Client to see if somehow I was doing this major blunder but I could not find anything suggestive of this.
Since the API
and the Client are hosted on a IIS server, I thought maybe that darn environment could be doing something but nope, I could not find anyone to blame there also.
So after a lot of here and there's, I finally decided to ask the pro's. It would be great if someone could help me and hopefully
resolve this issue of mine.
Thanks in anticipation.
回答1:
Okay, so regarding this issue, the solution that I've found is to change the session cookie name for each application which are interacting with each other.
In Startup / Configure()
, change the cookie name of the application :
app.UseSession(new SessionOptions() { Cookie = new CookieBuilder() { Name = ".AspNetCore.Session.MyApp1"}});
I do not thoroughly know why this was happening in the first place. I would really appreciate if someone could shed more light on this issue.
Thanks and I hope this helps someone who is facing a similar issue.
回答2:
Sorry, I hadn't noticed that you were on ASP.NET Core 2.1. Version 2.1 and later have GDPR-related changes that affect the default behavior of the .AspNetCore.Session
cookie, as in: it doesn't generate one by default.
Assuming your application doesn't run afoul of GDPR you can enable the previous Cookie-Session mapping behavior with two changes to your ConfigureServices() method.
The first, which you already have, is to change CookiePolicyOptions.CheckConsentNeed
from true
to false
(which you already do):
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
The second is to mark the session cookie as Essential:
services.AddSession(opts =>
{
opts.Cookie.IsEssential = true; // make the session cookie Essential
});
Read up more about this in Why isn't my session state working in ASP.NET Core? Session state, GDPR, and non-essential cookies.
来源:https://stackoverflow.com/questions/57317232/session-state-being-cleared-or-lost-after-one-ajax-call-to-net-core-2-1-applica