Чому властивість SessionID на сесії -об'єкт на сторінці ASP.NET змінюється між запитами?
У мене така сторінка:
...
<div>
SessionID: <%= SessionID %>
</div>
...
І вихід постійно змінюється щоразу, коли я натискаю F5, незалежно від браузера.
Чому властивість SessionID на сесії -об'єкт на сторінці ASP.NET змінюється між запитами?
У мене така сторінка:
...
<div>
SessionID: <%= SessionID %>
</div>
...
І вихід постійно змінюється щоразу, коли я натискаю F5, незалежно від браузера.
Відповіді:
Це причина
Під час використання стану сеансу на основі файлів cookie ASP.NET не виділяє сховище для даних сеансу, поки не буде використаний об'єкт Session. Як результат, новий ідентифікатор сеансу генерується для кожного запиту сторінки до доступу до об'єкта сеансу. Якщо у вашій програмі потрібен статичний ідентифікатор сеансу для всього сеансу, ви можете застосувати метод Session_Start у файлі Global.asax програми та зберігати дані в об’єкті Session, щоб виправити ідентифікатор сеансу, або ви можете використовувати код в іншій частині своєї додаток для явного зберігання даних в об'єкті Session.
http://msdn.microsoft.com/en-us/library/system.web.sesionstate.httpsesionstate.sessionid.aspx
Таким чином, якщо ви не отримаєте доступ до об'єкта сеансу в бекенде, з кожним запитом буде генеруватися новий ідентифікатор session
EDIT
Цей код потрібно додати у файл Global.asax. Він додає запис до об’єкта Session, щоб ви виправили сеанс, поки він не закінчиться.
protected void Session_Start(Object sender, EventArgs e)
{
Session["init"] = 0;
}
someid
сеанс, якщо він залишиться таким же. Враховуйте, що цій відповіді більше 4 років, не впевнений, чи були якісь зміни стосовно цього.
Є ще одна, більш підступна причина, чому це може статися навіть тоді, коли об’єкт сесії був ініціалізований, як показав Cladudio.
У Web.config, якщо є <httpCookies>
запис, встановлений, requireSSL="true"
але ви фактично не використовуєте HTTPS: для конкретного запиту cookie сеансу не надсилається (або, можливо, не повертається, я не впевнений, що), що означає що ви закінчуєте абсолютно новим сеансом для кожного запиту.
Я виявив цей складний шлях, витративши кілька годин, переходячи назад і назад між декількома комісіями в своєму контролі джерела, поки я не виявив, які конкретні зміни порушили мою програму.
У моєму випадку я зрозумів, що в файлі cookie сесії був домен, що включає www.
префікс, а я запитував сторінку з no www.
.
Додавання www.
до URL-адреси негайно вирішило проблему. Пізніше я змінив домен файлу cookie, який потрібно встановити .mysite.com
замість www.mysite.com
.
моя проблема полягала в тому, що у нас був цей набір у web.config
<httpCookies httpOnlyCookies="true" requireSSL="true" />
це означає, що при налагодженні в не-SSL (за замовчуванням) файл cookie auth не буде повернений на сервер. це означатиме, що сервер буде надсилати клієнту новий авторський cookie (з новим сеансом) для кожного запиту.
виправлення полягає в тому, щоб встановити Requiressl на false у web.config та true у web.release.config або включити SSL під час налагодження:
Використовуючи відповідь Невілла (видалення RequSSL = 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;
}
}
}
Іншою можливістю, яка змушує SessionID змінюватись між запитами, навіть коли визначено Session_OnStart та / або ініціалізацію сесії, є те, що ім'я хоста URL містить недійсний символ (наприклад, підкреслення). Я вважаю, що це специфічне для IE (не перевірено), але якщо ваша URL-адреса, скажімо http://server_name/app
, тоді IE заблокує всі файли cookie, і інформація про сеанс не буде доступною між запитами.
Насправді кожен запит розпочне окремий сеанс на сервері, тому якщо на вашій сторінці є кілька зображень, тегів сценарію тощо, то кожен із цих запитів GET призведе до іншого сеансу на сервері.
Додаткова інформація: http://support.microsoft.com/kb/316112
У моєму випадку це було багато в моїх розробках та тестових умовах. Спробувавши всі вищеперелічені рішення без успіху, я виявив, що мені вдалося виправити цю проблему, видаливши всі сесійні файли cookie. Розширення для веб-розробників робить це дуже просто. Я здебільшого використовую Firefox для тестування та розробки, але це траплялося і під час тестування в Chrome. Виправлення також працювало в Chrome.
Мені цього ще не доводилося робити у виробничому середовищі, і я не отримував жодних повідомлень про те, що люди не зможуть увійти. Це також, здавалося, відбулося лише після того, як сесійні файли cookie були захищені. Ніколи не бувало в минулому, коли вони не були захищеними.
у моєму випадку це було тому, що я змінював сеанс після перенаправлення із шлюзу у зовнішньому додатку , тому, що я використовував IP замість localhost у цій сторінці URL, насправді вважався різним веб-сайтом з різними сеансами.
Підводячи підсумок
зверніть більше уваги, якщо ви налагоджуєте розміщену програму на IIS замість IIS express та змішуєте вашу машину http: // Ip та http: // localhost на різних сторінках
Моя проблема стосувалася програми IPTV для Microsoft MediaRoom. Виявляється, що MPF-програми MRML не підтримують файли cookie; змінивши використання сеансів без cookie в web.config вирішило мою проблему
<sessionState cookieless="true" />
Ось НАДАЛЬНА стара стаття про це: Cookieless ASP.NET
Я перебуваю на .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".
Це змінювалося для мене, починаючи з .NET 4.7.2, і це було пов’язано з властивістю SameSite на файлі cookie сесії. Дивіться тут для отримання додаткової інформації: https://devblogs.microsoft.com/aspnet/upcoming-samesite-cookie-changes-in-asp-net-and-asp-net-core/
Значення за замовчуванням змінилося на "Lax" і почало ламати речі. Я змінив його на "Немає", і все працювало як очікувалося.
Будьте впевнені, що у вас немає дуже короткого затримки сеансу, а також переконайтесь, що якщо ви використовуєте сеанси на основі файлів cookie, ви приймаєте сеанс.
Веб-програма FireFox webDeveloperTool корисна в такі періоди, як ви можете бачити файли cookie, встановлені для вашої програми.
Скидання ідентифікатора сесії може мати багато причин. Однак будь-яке згадане вище не стосується моєї проблеми. Тому я опишу це для подальшого ознайомлення.
У моєму випадку новий сеанс, створений для кожного запиту, призводив до нескінченного циклу переадресації. Дія переспрямування відбувається в події OnActionExecuting .
Також я очищав усі заголовки http (також у події OnActionExecuting, використовуючи метод Response.ClearHeaders ), щоб запобігти кешування сайтів на стороні клієнта. Але цей метод очищає всі заголовки, включаючи інформацію про сеанс користувача, а отже, і всі дані у сховищі Temp (які я використовував пізніше в програмі). Тож навіть налаштування нового сеансу у події Session_Start не допомогло.
Щоб вирішити свою проблему, я забезпечив не видаляти заголовки, коли відбудеться перенаправлення.
Сподіваюся, це комусь допоможе.
Я зіткнувся з цим питанням по-іншому. Контролери, які мали цей атрибут [SessionState(SessionStateBehavior.ReadOnly)]
, читали з іншого сеансу, хоча я встановив значення в початковому сеансі при запуску програми. Я додавав значення сеансу через _layout.cshtml (можливо, не найкраща ідея?)
Очевидно, що проблема ReadOnly викликала проблему, оскільки коли я видалив атрибут, оригінальний сеанс (і SessionId) залишився б у такт. За допомогою рішення Клаудіо / Майкрософт це виправили.