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


142

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

У меня есть такая страница:

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

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

Ответы:


225

Это причина

При использовании состояния сеанса на основе файлов 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;
}

23
Я не знал этого, никогда не
сталкивался

1
@Cladudio не могли бы вы просто добавить одну строку кода, и ваш ответ идеально подходит. Интересная информация выходит из интересного вопроса ... плюс один? ;)
Себ Нильссон

2
Интересно, что это исправляет мою проблему - но проблема проявилась только через 6 месяцев использования кодовой базы без проблем. Я не могу придумать причину, по которой это внезапно изменилось бы. Может ли кто-нибудь предложить причину, по которой сессионный идентификатор внезапно будет сброшен, если не было раньше?
Moo

2
@KumarHarsh: после сохранения какого-либо объекта в сеансе идентификатор сеанса будет исправлен. Это то, что я хотел сказать, «если вы не обращаетесь к своему объекту сеанса в бэкэнде ...». После того, как вы назначите someidсеанс, если останется прежним. Примите во внимание, что этому ответу более 4 лет, не уверен, что было какое-либо изменение по отношению к этому.
Клаудио Реди

9
Я заметил, что простое добавление метода Session_Start WITH NOTHING IN IT в мой Global.asax сделало эту работу. Спасибо @Claudio за совет, хотя.
Педро

92

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

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

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


5
Я знал это, но все еще забывал об этом каждые 3 месяца или около того и проводил пару часов в отладке ..
sotn

В моем случае я тестировал на localhost, а «requireSSL» в web.config был установлен как «true». Спасибо.
Уильям Перейра

это был мой случай, и я потратил слишком много времени, пытаясь выяснить это (имел красную сельдь с различными файлами web.config).
jmoreno

Ваше предложение выше все еще помогает в 2018 году. Это наиболее частый сценарий. Спасибо!
Виджай Бансал

5

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


5

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

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

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

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

включить SSL


Чем это отличается от ответа Невилла Кука от 2011 года?
Ян Кемп

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

2

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

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

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


2

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

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


Обновление: это начало происходить только после того, как мы изменили куки-файл сессии, чтобы сделать его безопасным. Я определил, что именно эта проблема была вызвана наличием двух или более файлов cookie сеанса в браузере с одинаковым путем и доменом. Проблема всегда была та, у которой было пустое или нулевое значение. После удаления этого файла cookie проблема была решена. Я также добавил код в метод Global.asax.cs Sessin_Start, чтобы проверить наличие этого пустого cookie и, если это так, установить дату истечения срока его действия в прошлом.
Мэтт Л

2

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

В итоге

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


1

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

<sessionState cookieless="true"  />

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


1

Я на .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',                           // important
            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".


1

Это изменилось для меня, начиная с .NET 4.7.2, и это было связано со свойством SameSite в файле cookie сеанса. Смотрите здесь для получения дополнительной информации: https://devblogs.microsoft.com/aspnet/upcoming-samesite-cookie-changes-in-asp-net-and-asp-net-core/

Значение по умолчанию изменилось на «Lax» и начало ломать вещи. Я изменил его на «Нет», и все заработало, как и ожидалось.


0

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

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


2
Я предполагаю, что мое время ожидания сеанса не установлено ниже одной секунды. Он меняется с каждым быстрым нажатием F5.
Себ Нильссон

0

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

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

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

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

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


0

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.