Идентификатор сеанса всегда меняется на ASP. NET Core + Redis + nginx - PullRequest
6 голосов
/ 07 января 2020

Пример проекта 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;
        }

Получить идентификатор сеанса: 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?}");
            });
        }

URL доступа: localhost и refre sh снова и снова, идентификатор сеанса будет постоянно меняться.

Я проверил ключи в Redis Server, он всегда генерирует новый ключ при обновлении страницы sh. (egmasterdef69307-fbd3-c6ed-91d2-009b2306f902)

Если я просто использую сервер (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;
    }

Идентификатор сеанса не изменится.

Кто-нибудь знает, что это будет оценено.

Спасибо

Ответы [ 5 ]

3 голосов
/ 12 января 2020

Я на самом деле не могу воспроизвести проблему на ма c с конфигурацией (нагрузка 2 локальных серверов сбалансирована через nginx и подключена к тому же локальному распределенному кешу redis)

В любом случае, если применимо, есть Вы пытались включить ip_hash в nginx восходящем модуле?

Из раздела устойчивости сеансов в nginx do c:

Если есть это необходимость t ie клиента к определенному серверу приложений - другими словами, сделать сеанс клиента «липким» или «постоянным» с точки зрения постоянной попытки выбора конкретного сервера - загрузка ip-ha sh Можно использовать механизм балансировки.

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;
}

Если это не решает вашу проблему, пожалуйста, посмотрите на похожие проблемы при обмене стека:

2 голосов
/ 16 января 2020

Решено с помощью

var redis = ConnectionMultiplexer.Connect("<REDIS URI>");

services.AddDataProtection().PersistKeysToRedis(redis, "DataProtection-Keys");

Артикул:

https://onecodex.ch/blogsdotnetcoredistributed-redis-cache/

Необходимый пакет: https://www.nuget.org/packages/Microsoft.AspNetCore.DataProtection.Redis/

2 голосов
/ 09 января 2020

Если для свойства CheckConsentNeeded назначено значение true, приложение не будет устанавливать необязательный рецепт ie без согласия пользователя. Это включает в себя сессионный повар ie, который по умолчанию не является обязательным.

Существует как минимум три решения вашей проблемы:

  1. Вы можете установить CheckConsentNeeded в false.
    ...

    options.CheckConsentNeeded = context => false;

    ...

Это отключит функцию согласия всего повара ie.

Вы можете пометить сессионного повара ie как обязательное.
    ...

    services.AddSession(options =>
    {
        options.IdleTimeout = TimeSpan.FromSeconds(100);
        options.Cookie.IsEssential = true;
    });

    ...

Это позволит приложению установить сессионного повара ie независимо от согласия пользователя.

Вы можете оставить все как есть. В этом случае сеанс начнется только после того, как пользователь нажмет кнопку «Принять» на всплывающей подсказке «Повар» ie.
1 голос
/ 14 января 2020

Похоже, что ваши сеансы не распределяются между вашими бэкэндами (серверами).

Вы должны проверить, где хранятся ваши куки, и является ли это "местоположение" общим для ваших нескольких серверов.

Если вы используете Redis: они используют один и тот же Redis? одно и то же пространство имен? Если это локальное хранилище на диске, они совместно используют один и тот же каталог и т. Д. c.

или, как сказал @Gomino, вы можете использовать nginx sticky session для go на одном и том же сервере каждый раз ( когда у вас есть сеанс). Но это не относится к конфигурации nginx.

0 голосов
/ 16 января 2020

Согласно этой статье. https://medium.com/@LuizAdolphs / asp - net ядро-распределенная сессия-с-redis-8ce8bacf26cd

Правильная конфигурация Nginx:

worker_processes 1;

events { worker_connections 1024; }

http {

    sendfile on;

    upstream app_server {
        server app_1:5000;
        server app_2:5050;
    }

    server {
        listen 80;

        location / {
            proxy_pass         http://app_server;
            proxy_redirect     off;
            proxy_set_header   Host $host;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Host $server_name;
        }
    }
}

Пожалуйста, взгляните на X-Forwarded-Host. Попробуйте использовать это, если это не решит проблему, это может быть проблемой в конфигурации Redis.

...