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我一直忽略了这一点,因为我是如何生成的