Session State being cleared or lost after one AJAX call to .NET CORE 2.1 application hosted on IIS server

ε祈祈猫儿з 提交于 2020-01-25 06:51:08

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!