The sample project https://github.com/xingyu217/Redis-nginx-aspnetcore-session nginx.config:
upstream study_server{
server localhost:8011 weight=1;
server localhost:8013 weight=1;
#server localhost:8014 weight=1;
#server 172.17.16.147:8012 weight=2;
#server 172.17.16.147:8011 weight=2;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
#root html;
#index index.html index.htm;
proxy_pass http://study_server/;
proxy_cookie_path ~*^/.* /;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
Get session id: ViewBag.seId= HttpContext.Session.Id;
Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
//services.AddDistributedMemoryCache();
services.AddDistributedRedisCache(options =>
{
options.Configuration = Configuration.GetConnectionString("RedisConnection");
options.InstanceName = "master";
});
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromSeconds(100);
//options.Cookie.HttpOnly = true;
});
//services.AddSession();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
//app.UseDeveloperExceptionPage();
//app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseSession();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
Access URL: localhost and refresh again and again, the session id will be always changing.
I checked keys in redis server, it always generate the new key when refresh page. (e.g.masterdef69307-fbd3-c6ed-91d2-009b2306f902)
If I just use a server (localhost:8011):
upstream study_server{
server localhost:8011 weight=1;
#server localhost:8013 weight=1;
#server localhost:8014 weight=1;
#server 172.17.16.147:8012 weight=2;
#server 172.17.16.147:8011 weight=2;
}
The session id won't be changed.
Anyone know it will be appreciated.
Thanks
Episode 16: Using Redis for Distributed User Sessions in ASP.NET Core | ASP.NET session storage is useful for storing state across page views. In single server situations it’s simple to set up because ASP.NET supports in-memory s... | Request Metrics
This session has unique ID by which it is uniquely identify a browser with the help of session data on the server. This SessionID value is randomly generated value by the ASP.NET and will be stored in session cookie in the browser only which is non-expiring.
So basically, unless you access your session object on the backend, a new sessionId will be generated with each request This code must be added on the file Global.asax. It adds an entry to the Session object so you fix the session until it expires. protected void Session_Start (Object sender, EventArgs e) { Session ["init"] = 0; }
This is the reason. When using cookie-based session state, ASP.NET does not allocate storage for session data until the Session object is used. As a result, a new session ID is generated for each page request until the session object is accessed.
I actually cannot reproduce the problem on a mac with the configuration (2 local servers load balanced via nginx and connected to the same local redis distributed cache)
Anyways, if applicable, have you tried enabled ip_hash
in nginx upstream module ?
From the sessions persistance section in nginx doc:
If there is the need to tie a client to a particular application server — in other words, make the client’s session “sticky” or “persistent” in terms of always trying to select a particular server — the ip-hash load balancing mechanism can be used.
upstream study_server{
ip_hash;
server localhost:8011 weight=1;
server localhost:8013 weight=1;
#server localhost:8014 weight=1;
#server 172.17.16.147:8012 weight=2;
#server 172.17.16.147:8011 weight=2;
}
If that's not solving your issue please have a look at similar issues on stack exchange:
https://serverfault.com/questions/133500/nginx-sticky-session-and-iis
ASP.NET: Session.SessionID changes between requests
If the CheckConsentNeeded
property is assigned with true
, the application will not set any non-essential cookie without user consent. This includes the session cookie, which is non-essential by default.
There are at least three solutions to your problem:
CheckConsentNeeded
to false
. ...
options.CheckConsentNeeded = context => false;
...
This will disable the whole cookie consent feature.
...
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromSeconds(100);
options.Cookie.IsEssential = true;
});
...
This will allow the application to set the session cookie regardless of user's consent.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With