ASP.NET: изменения Session.SessionID между запросами

Почему свойство SessionID в сеансе -объект на странице ASP.NET-страницы изменяется между запросами?

У меня есть страница вроде этого:

...
<div>
    SessionID: <%= SessionID %>
</div>
...

И вывод продолжает меняться каждый раз, когда я нажимаю F5, независимо от браузера.

Ответ 1

Вот почему

При использовании состояния сеанса на основе файлов cookie ASP.NET не выделяет память для данных сеанса до тех пор, пока не будет использован объект Session. В результате для каждого запроса страницы создается новый идентификатор сеанса, пока не будет доступен доступ к объекту сеанса. Если вашему приложению требуется статический идентификатор сеанса для всего сеанса, вы можете либо реализовать метод Session_Start в файле приложения Global.asax и сохранить данные в объекте Session, чтобы исправить идентификатор сеанса, либо использовать код в другой части вашего приложение для явного хранения данных в объекте Session.

http://msdn.microsoft.com/en-us/library/system.web.sessionstate.httpsessionstate.sessionid.aspx

Таким образом, если вы не получите доступ к объекту сеанса на сервере, новый sessionId будет сгенерирован с каждым запросом

ИЗМЕНИТЬ

Этот код должен быть добавлен в файл Global.asax. Он добавляет запись в объект Session, поэтому вы фиксируете сеанс до истечения срока его действия.

protected void Session_Start(Object sender, EventArgs e) 
{
    Session["init"] = 0;
}

Ответ 2

Существует еще одна, более коварная причина, почему это может произойти, даже если объект Session был инициализирован, как продемонстрировано Cladudio.

В Web.config, если есть запись <httpCookies>, которая установлена ​​в requireSSL="true", но вы фактически не используете HTTPS: для конкретного запроса куки файлы сеанса не отправляются (или, возможно, не возвращаются, Я не уверен, что), что означает, что вы получаете совершенно новый сеанс для каждого запроса.

Я нашел этот трудный путь, проводя несколько часов, переходящих между несколькими коммитами в моем контроле источника, пока не нашел, какое конкретное изменение нарушило мое приложение.

Ответ 3

В моем случае я понял, что в cookie сессии был домен, который включал префикс www., в то время как я запрашивал страницу без www..
Добавление www. в URL немедленно устранило проблему. Позже я изменил домен cookie на .mysite.com вместо www.mysite.com.

Ответ 4

Используя ответ Невилла (удаление requireSSL = true, в web.config) и слегка модифицирующий код Джоэла Эфирона, вот код, который должен обрабатывать сайт, который работает как в режиме SSL, так и в режиме без SSL, в зависимости от пользователя и (я перескакиваю обратно в код и еще не тестировал его на SSL, но ожидаю, что он будет работать - будет слишком занят позже, чтобы вернуться к этому, так вот:

if (HttpContext.Current.Response.Cookies.Count > 0)
        {
            foreach (string s in HttpContext.Current.Response.Cookies.AllKeys)
            {
                if (s == FormsAuthentication.FormsCookieName || s.ToLower() == "asp.net_sessionid")
                {
                    HttpContext.Current.Response.Cookies[s].Secure = HttpContext.Current.Request.IsSecureConnection;
                }
            }
        }

Ответ 5

Другая возможность, которая заставляет SessionID изменяться между запросами, даже если Session_OnStart определен и/или инициализирован сеанс, заключается в том, что имя хоста URL содержит недопустимый символ (например, подчеркивание). Я считаю, что это специфичный для IE (не проверенный), но если ваш URL-адрес, скажем, http://server_name/app, тогда IE блокирует все файлы cookie, и ваша информация сеанса не будет доступна между запросами.

Фактически каждый запрос будет разворачивать отдельный сеанс на сервере, поэтому, если ваша страница содержит несколько изображений, теги script и т.д., то каждый из этих запросов GET приведет к другому сеансу на сервере.

Дополнительная информация: http://support.microsoft.com/kb/316112

Ответ 6

Моя проблема была связана с приложением Microsoft MediaRoom IPTV. Оказывается, что приложения MPF MRML не поддерживают файлы cookie; переход на использование cookieless сессий в web.config решил мою проблему

<sessionState cookieless="true"  />

Здесь ДЕЙСТВИТЕЛЬНО старая статья об этом: Cookieless ASP.NET

Ответ 7

моя проблема заключалась в том, что у нас был этот набор в web.config

<httpCookies httpOnlyCookies="true" requireSSL="true" />

это означает, что при отладке не-SSL (по умолчанию) файл cookie auth не будет отправлен обратно на сервер. это означало бы, что сервер отправит новый файл cookie (с новым сеансом) для каждого запроса обратно клиенту.

Исправление состоит в том, чтобы либо установить requiressl на false в web.config, либо true в файле web.release.config или включить SSL при отладке:

включить SSL

Ответ 8

В моем случае это происходило в моей среде разработки и тестирования. После успешного выполнения всех вышеперечисленных решений я обнаружил, что смог исправить эту проблему, удалив все файлы сеансов. Расширение веб-разработчика делает это очень легко. В основном я использую Firefox для тестирования и разработки, но это также произошло во время тестирования в Chrome. Исправление также работало в Chrome.

Мне не приходилось делать это еще в производственной среде и не получало сообщений о том, что люди не могут войти в систему. Это также, похоже, произошло после того, как файлы cookie сеанса были безопасными. Это никогда не случалось в прошлом, когда они были не в безопасности.

Ответ 9

в моем случае это было из-за того, что я изменял сессию после перенаправления со шлюза во внешнее приложение, поэтому, поскольку я использовал IP вместо localhost в URL-адресе страницы, на самом деле это был другой веб-сайт с разными сессиями.

В итоге

уделять больше внимания, если вы отлаживаете размещенное приложение на IIS вместо IIS Express и смешиваете свою машину http://Ip и http://localhost на разных страницах

Ответ 10

Убедитесь, что у вас нет слишком короткого таймаута сеанса, а также убедитесь, что если вы используете сеансы на основе файлов cookie, которые вы принимаете в сеансе.

FireFox webDeveloperToolbar помогает в таких случаях, поскольку вы можете видеть файлы cookie, установленные для вашего приложения.

Ответ 11

Сброс идентификатора сеанса может иметь много причин. Однако любые упомянутые выше не связаны с моей проблемой. Поэтому я опишу его для будущей справки.

В моем случае новый сеанс, созданный по каждому запросу, привел к бесконечному циклу перенаправления. Действие перенаправления происходит в событии OnActionExecuting.

Также я очистил все заголовки http (также в событии OnActionExecuting с использованием метода Response.ClearHeaders), чтобы предотвратить кеширование сайтов на стороне клиента. Но этот метод очищает все заголовки, включая информацию о сеансе пользователя, и, следовательно, все данные в хранилище Temp (которые я использовал позже в программе). Поэтому даже установка нового сеанса в событии Session_Start не помогла.

Чтобы решить мою проблему, я решил не удалять заголовки, когда происходит перенаправление.

Надеюсь, что это поможет кому-то.

Ответ 12

Я столкнулся с этой проблемой по-другому. Контроллеры, которые имели этот атрибут [SessionState(SessionStateBehavior.ReadOnly)], читали с другого сеанса, даже если я установил значение в исходном сеансе при запуске приложения. Я добавлял значение сеанса через _layout.cshtml(может быть, не лучшая идея?)

Очевидно, что ReadOnly вызывает проблему, потому что когда я удаляю атрибут, исходный сеанс (и SessionId) будет оставаться в такте. Решение Claudio/Microsoft исправило это.

Ответ 13

Я на.NET Core 2.1, и я хорошо знаю, что вопрос не в Core. Тем не менее, Интернета не хватает, и Google привел меня сюда, так надеясь сэкономить кому-то несколько часов.


Startup.cs

services.AddCors(o => o.AddPolicy("AllowAll", builder =>
            {
                builder
                    .WithOrigins("http://localhost:3000")     // important
                    .AllowCredentials()                       // important
                    .AllowAnyMethod()
                    .AllowAnyHeader();       // obviously just for testing
            }));

client.js

const resp = await fetch("https://localhost:5001/api/user", {
            method: 'POST',
            credentials: 'include',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(data)
        })

Controllers/LoginController.cs

namespace WebServer.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class UserController : ControllerBase
    {
        [HttpPost]
        public IEnumerable<string> Post([FromBody]LoginForm lf)
        {
            string prevUsername = HttpContext.Session.GetString("username");
            Console.WriteLine("Previous username: " + prevUsername);

            HttpContext.Session.SetString("username", lf.username);

            return new string[] { lf.username, lf.password };
        }
    }
}

Обратите внимание, что запись и чтение сеанса работает, но, похоже, файлы cookie не передаются в браузер. По крайней мере, я нигде не мог найти заголовок "Set-Cookie".