为来自另一个域的每个请求创建一个会话
A session is created for each request from another domain
我使用 ASP.NET Core Web API 2.0 和 Angular 5.
我需要使用购物车会话。当我从 swagger 发送请求时,服务器对所有请求使用一个会话,当我从 Angular(不同域)发送请求时,服务器在每个请求上创建新会话。
我使用 CORS:
services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowCredentials()
.SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowAnyHeader();
}));
并添加到 CartController 上面
[EnableCors("MyPolicy")]
我也初始化会话
app.Run(async (context) =>
{
if (!context.Session.Keys.Contains("Cart"))
{
context.Session.Set<Cart>("Cart", new Cart());
}
else
{
context.Session.Get<Cart>("Cart");
}
});
并添加了服务
services.AddRouting();
services.AddScoped(SessionCart.GetCart);
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddMvc().AddSessionStateTempDataProvider();
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.None;
});
SessionCart
public static Cart GetCart(IServiceProvider services)
{
ISession session = ServiceProviderServiceExtensions.GetRequiredService<IHttpContextAccessor>(services)?.HttpContext.Session;
SessionCart cart = session?.Get<SessionCart>("Cart") ?? new SessionCart();
cart.Session = session;
return cart;
}
public override void AddItem(DishModel product, int quantity)
{
base.AddItem(product, quantity);
Session.Set("Cart", this);
}
我该如何解决这个问题?
一个API是无状态的,也就是说每个请求都是独立的。因此,您将无法在 API 端保留任何内容,在 "session".
你想做什么你可以通过其他方式实现,具体的解决方案取决于你的要求。
一种方法是在 JavaScript 一侧跟踪您的购物车,并使用 API 存储您需要的任何东西。您可以让用户添加/删除/做他们想做的任何事情,当他们提交时,您可以一次性将购物车的内容发送到 api。
我工作的一些系统需要跟踪购物车上的每个操作,报告物品/放弃率,诸如此类。如果是这种情况,那么您可以最初创建一个购物车,跟踪它从 api / 数据库返回的 ID,然后在每次添加或删除某些内容时发出请求。购物车的 ID 用于跟踪数据,然后您不需要在会话中保留任何内容。
所以,根据你的要求选择你的毒药。
我使用 ASP.NET Core Web API 2.0 和 Angular 5.
我需要使用购物车会话。当我从 swagger 发送请求时,服务器对所有请求使用一个会话,当我从 Angular(不同域)发送请求时,服务器在每个请求上创建新会话。
我使用 CORS:
services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowCredentials()
.SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowAnyHeader();
}));
并添加到 CartController 上面
[EnableCors("MyPolicy")]
我也初始化会话
app.Run(async (context) =>
{
if (!context.Session.Keys.Contains("Cart"))
{
context.Session.Set<Cart>("Cart", new Cart());
}
else
{
context.Session.Get<Cart>("Cart");
}
});
并添加了服务
services.AddRouting();
services.AddScoped(SessionCart.GetCart);
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddMvc().AddSessionStateTempDataProvider();
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.None;
});
SessionCart
public static Cart GetCart(IServiceProvider services)
{
ISession session = ServiceProviderServiceExtensions.GetRequiredService<IHttpContextAccessor>(services)?.HttpContext.Session;
SessionCart cart = session?.Get<SessionCart>("Cart") ?? new SessionCart();
cart.Session = session;
return cart;
}
public override void AddItem(DishModel product, int quantity)
{
base.AddItem(product, quantity);
Session.Set("Cart", this);
}
我该如何解决这个问题?
一个API是无状态的,也就是说每个请求都是独立的。因此,您将无法在 API 端保留任何内容,在 "session".
你想做什么你可以通过其他方式实现,具体的解决方案取决于你的要求。
一种方法是在 JavaScript 一侧跟踪您的购物车,并使用 API 存储您需要的任何东西。您可以让用户添加/删除/做他们想做的任何事情,当他们提交时,您可以一次性将购物车的内容发送到 api。
我工作的一些系统需要跟踪购物车上的每个操作,报告物品/放弃率,诸如此类。如果是这种情况,那么您可以最初创建一个购物车,跟踪它从 api / 数据库返回的 ID,然后在每次添加或删除某些内容时发出请求。购物车的 ID 用于跟踪数据,然后您不需要在会话中保留任何内容。
所以,根据你的要求选择你的毒药。