C# 对IIS服务器上托管的.NET CORE 2.1应用程序进行一次AJAX调用后,会话状态被清除或丢失

C# 对IIS服务器上托管的.NET CORE 2.1应用程序进行一次AJAX调用后,会话状态被清除或丢失,c#,ajax,asp.net-core-mvc,asp.net-core-webapi,session-state,C#,Ajax,Asp.net Core Mvc,Asp.net Core Webapi,Session State,我遇到了这个问题,几个小时来我一直在挠头 问题是:我在Login上创建的会话状态在调用API控制器后神秘地被清除或丢失,该控制器也在.NET CORE 2.1中。当我调用如下所示的API方法时,就会发生这种情况: [Authorize(Policy = "AdminViewPolicy")] [HttpGet("GetAllUsersId")] public IActionResult GetAllUsersId() { var user = _u

我遇到了这个问题,几个小时来我一直在挠头

问题是:我在
Login
上创建的会话状态在调用
API
控制器后神秘地被清除或丢失,该控制器也在.NET CORE 2.1中。当我调用如下所示的
API
方法时,就会发生这种情况:

    [Authorize(Policy = "AdminViewPolicy")]
    [HttpGet("GetAllUsersId")]
    public IActionResult GetAllUsersId()
    {
        var user = _userService.GetAllUsersId();
        return Ok(new
        {
            data = user
        });
    }
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();
    }
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);
}
此方法的角色和其他方面工作正常。这就是我如何称呼这个动作方法的:

$.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);
    },
});
API
项目的Startup.cs配置如下所示:

    [Authorize(Policy = "AdminViewPolicy")]
    [HttpGet("GetAllUsersId")]
    public IActionResult GetAllUsersId()
    {
        var user = _userService.GetAllUsersId();
        return Ok(new
        {
            data = user
        });
    }
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();
    }
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);
}
这部分会变得棘手。当我从
视图
调用AJAX函数时,AJAX成功地调用了
API
方法并获得所需的数据,但同时AJAX调用以某种方式清除了我的会话,因为一旦我导航到其他页面或提交表单,上面显示的
SessionTimeout
属性被调用,我被踢出系统

我已经检查了我的web浏览器上的所有控制台日志、网络请求和应用程序存储,但我找不到罪犯。我还检查了API和客户端中的逻辑,看看我是否犯了这个大错误,但我找不到任何暗示这一点的东西

由于
API
和客户机托管在IIS服务器上,我认为该死的环境可能正在做一些事情,但没有,我也找不到任何人对此负责

所以,在经历了很多这样那样的事情之后,我终于决定去问问专业人士。如果有人能帮我解决我的这个问题,那就太好了


非常感谢。

对不起,我没有注意到您正在使用ASP.NET Core 2.1。版本2.1及更高版本具有与GDPR相关的更改,这些更改会影响
.AspNetCore.Session
cookie的默认行为,如:默认情况下,它不会生成一个

假设您的应用程序没有与GDPR冲突,您可以通过对ConfigureServices()方法的两个更改来启用以前的Cookie会话映射行为

您已经拥有的第一个选项是更改
CookiePolicyOptions。CheckApproveNeed
true
更改为
false
(您已经这样做了):

services.Configure(选项=>
{
//此lambda确定给定请求是否需要非必要cookie的用户同意。
options.checkApprovered=context=>false;
options.MinimumSameSitePolicy=SameSiteMode.None;
});
第二个是将会话cookie标记为必需的:

services.AddSession(opts=>
{
opts.Cookie.IsEssential=true;//使会话Cookie成为必需的
});

请在中详细阅读。

抱歉,我没有注意到您在ASP.NET Core 2.1上。版本2.1及更高版本具有与GDPR相关的更改,这些更改会影响
.AspNetCore.Session
cookie的默认行为,如:默认情况下,它不会生成一个

假设您的应用程序没有与GDPR冲突,您可以通过对ConfigureServices()方法的两个更改来启用以前的Cookie会话映射行为

您已经拥有的第一个选项是更改
CookiePolicyOptions。CheckApproveNeed
true
更改为
false
(您已经这样做了):

services.Configure(选项=>
{
//此lambda确定给定请求是否需要非必要cookie的用户同意。
options.checkApprovered=context=>false;
options.MinimumSameSitePolicy=SameSiteMode.None;
});
第二个是将会话cookie标记为必需的:

services.AddSession(opts=>
{
opts.Cookie.IsEssential=true;//使会话Cookie成为必需的
});

请在中详细阅读。

好的,关于这个问题,我找到的解决方案是更改每个相互交互的应用程序的会话cookie名称

在Startup/Configure()
中,更改应用程序的cookie名称:

app.UseSession(new SessionOptions() { Cookie = new CookieBuilder() { Name = ".AspNetCore.Session.MyApp1"}});
我不完全知道为什么会发生这种情况。如果有人能在这个问题上透露更多信息,我将不胜感激


谢谢,我希望这对面临类似问题的人有所帮助。

好的,关于这个问题,我找到的解决方案是更改每个相互交互的应用程序的会话cookie名称

在Startup/Configure()
中,更改应用程序的cookie名称:

app.UseSession(new SessionOptions() { Cookie = new CookieBuilder() { Name = ".AspNetCore.Session.MyApp1"}});
我不完全知道为什么会发生这种情况。如果有人能在这个问题上透露更多信息,我将不胜感激


谢谢,我希望这对面临类似问题的人有所帮助。

听起来您可能在web浏览器中关闭了Cookie。对API请求的HTTP响应应该包括一个带有名称、值、域等字符串的头。从浏览器到同一站点的后续HTTP请求应包括带有-属于该域的Cookie的名称=值对的分隔列表。@AlwaysLearning感谢您的评论,但我正在客户端生成
会话
,从服务器上得到的唯一东西是成功授权时生成的
令牌
。客户端有一个
会话
,用于管理一些变量,当我想通过头从
API
请求某些内容时,我会使用这些变量。我不是用Token定义任何显式的
Cookie
,我想你指的是JWT?Configure/ConfigureServices代码中没有任何内容表明您正在将JSON Web令牌身份验证绑定到服务器端会话。因此,每个请求都将创建一个新的服务器端会话。@AlwaysLearning我一直忽略了这一点,因为我是如何生成的