ASP.NET: Session.SessionID thay đổi giữa các yêu cầu


142

Tại sao thuộc tính SessionID trên Phiên -object trong trang ASP.NET thay đổi giữa các yêu cầu?

Tôi có một trang như thế này:

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

Và đầu ra liên tục thay đổi mỗi khi tôi nhấn F5, độc lập với trình duyệt.

Câu trả lời:


225

Đây là lý do

Khi sử dụng trạng thái phiên dựa trên cookie, ASP.NET không phân bổ lưu trữ cho dữ liệu phiên cho đến khi đối tượng Phiên được sử dụng. Do đó, ID phiên mới được tạo cho mỗi yêu cầu trang cho đến khi đối tượng phiên được truy cập. Nếu ứng dụng của bạn yêu cầu ID phiên tĩnh cho toàn bộ phiên, bạn có thể triển khai phương thức Session_Start trong tệp Global.asax của ứng dụng và lưu trữ dữ liệu trong đối tượng Phiên để sửa ID phiên hoặc bạn có thể sử dụng mã trong một phần khác của ứng dụng để lưu trữ dữ liệu rõ ràng trong đối tượng Phiên.

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

Vì vậy, về cơ bản, trừ khi bạn truy cập đối tượng phiên của mình vào phần phụ trợ, một sessionId mới sẽ được tạo với mỗi yêu cầu

BIÊN TẬP

Mã này phải được thêm vào tệp Global.asax. Nó thêm một mục vào đối tượng Phiên để bạn sửa phiên cho đến khi hết hạn.

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

23
Tôi không biết điều đó, chưa bao giờ có vấn đề với nó nhưng điều đó thật thú vị khi biết
Pharabus

1
@Cladudio bạn có thể chỉ cần ném vào một dòng mã và câu trả lời của bạn là hoàn hảo. Thông tin thú vị đến từ một câu hỏi thú vị ... cộng với một? ;)
Seb Nilsson

2
Thật thú vị, điều này khắc phục vấn đề của tôi - nhưng vấn đề chỉ xuất hiện sau khoảng 6 tháng sử dụng codebase mà không gặp vấn đề gì. Tôi không thể nghĩ ra bất kỳ lý do nào khiến điều này đột nhiên thay đổi - bất cứ ai cũng có thể đề xuất một lý do tại sao sessionid đột nhiên được thiết lập lại khi nó không có trước đây?
Moo

2
@KumarHarsh: một khi bạn lưu trữ bất kỳ đối tượng nào trên phiên, id phiên sẽ được sửa. Đó là những gì tôi muốn nói với "trừ khi bạn truy cập đối tượng phiên của mình vào phần phụ trợ ...". Một khi bạn chỉ định someidphiên nếu sẽ giữ nguyên. Hãy xem xét rằng câu trả lời này đã hơn 4 năm tuổi, không chắc có bất kỳ sửa đổi nào liên quan đến vấn đề này hay không.
Claudio Redi

9
Tôi nhận thấy rằng chỉ cần thêm phương thức Session_Start KHÔNG CÓ NÓ TRONG CNTT vào Global.asax của tôi đã khiến công việc này hoạt động. Cảm ơn @Claudio cho tiền boa mặc dù.
Pedro

92

Có một lý do khác, xảo quyệt hơn, tại sao điều này có thể xảy ra ngay cả khi đối tượng Phiên đã được khởi tạo như được trình bày bởi Cladudio.

Trong Web.config, nếu có một <httpCookies>mục được đặt thành requireSSL="true"nhưng bạn không thực sự sử dụng HTTPS: cho một yêu cầu cụ thể, thì cookie phiên không được gửi (hoặc có thể không được trả lại, tôi không chắc đó là gì) rằng bạn kết thúc với một phiên hoàn toàn mới cho mỗi yêu cầu.

Tôi đã tìm thấy điều này một cách khó khăn, dành vài giờ qua lại giữa một số cam kết trong kiểm soát nguồn của tôi, cho đến khi tôi tìm thấy những thay đổi cụ thể đã phá vỡ ứng dụng của tôi.


5
Tôi biết điều này nhưng vẫn quên nó cứ sau 3 tháng hoặc lâu hơn và dành vài giờ để gỡ lỗi ..
sotn

Trong trường hợp của tôi, tôi đã thử nghiệm trên localhost và "allowSSL" trong web.config được đặt là "true". Cảm ơn.
William Pereira

đây là trường hợp của tôi và tôi đã dành quá nhiều thời gian để cố gắng tìm ra nó (có một cá trích đỏ với các tệp web.config khác nhau).
jmoreno

Đề xuất của bạn ở trên vẫn giúp ích trong năm 2018. Đây là tình huống thường xuyên nhất. Cảm ơn!
Vijay Bansal

5

Trong trường hợp của tôi, tôi đã tìm ra rằng cookie phiên có một tên miền bao gồm www.tiền tố, trong khi tôi đang yêu cầu trang không có www..
Thêm www.vào URL ngay lập tức khắc phục vấn đề. Sau đó, tôi đã thay đổi tên miền của cookie để được đặt thành .mysite.comthay vì www.mysite.com.


5

vấn đề của tôi là chúng tôi đã có bộ này trong web.config

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

điều này có nghĩa là khi gỡ lỗi không phải SSL (mặc định), cookie xác thực sẽ không được gửi trở lại máy chủ. điều này có nghĩa là máy chủ sẽ gửi cookie xác thực mới (với phiên mới) cho mọi yêu cầu quay lại máy khách.

cách khắc phục là đặt Yêu cầu thành sai trong web.config và đúng trong web.release.config hoặc bật SSL trong khi gỡ lỗi:

bật SSL


Điều này khác với câu trả lời của Neville Cook từ năm 2011 như thế nào?
Ian Kemp

4

Sử dụng câu trả lời của Neville (xóa requestSSL = true, trong web.config) sửa đổi một chút mã của Joel Etherton, đây là mã nên xử lý một trang web chạy ở cả chế độ SSL và chế độ không SSL, tùy thuộc vào người dùng và trang (I đang quay trở lại mã và chưa thử nghiệm nó trên SSL, nhưng hy vọng nó sẽ hoạt động - sau này sẽ quá bận để quay lại vấn đề này, vì vậy đây là:

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

Một khả năng khác làm cho Phiên ID thay đổi giữa các yêu cầu, ngay cả khi Phiên_OnStart được xác định và / hoặc Phiên đã được khởi tạo, đó là tên máy chủ URL chứa ký tự không hợp lệ (chẳng hạn như dấu gạch dưới). Tôi tin rằng đây là IE cụ thể (chưa được xác minh), nhưng nếu URL của bạn là http://server_name/app, thì IE sẽ chặn tất cả các cookie và thông tin phiên của bạn sẽ không thể truy cập được giữa các yêu cầu.

Trên thực tế, mỗi yêu cầu sẽ tạo ra một phiên riêng biệt trên máy chủ, vì vậy nếu trang của bạn chứa nhiều hình ảnh, thẻ script, v.v., thì mỗi yêu cầu GET đó sẽ dẫn đến một phiên khác nhau trên máy chủ.

Thông tin khác: http://support.microsoft.com/kb/316112


2

Trong trường hợp của tôi, điều này đã xảy ra rất nhiều trong môi trường phát triển và thử nghiệm của tôi. Sau khi thử tất cả các giải pháp trên mà không có bất kỳ thành công nào, tôi thấy rằng tôi có thể khắc phục vấn đề này bằng cách xóa tất cả các cookie phiên. Phần mở rộng nhà phát triển web làm cho điều này rất dễ làm. Tôi chủ yếu sử dụng Firefox để thử nghiệm và phát triển, nhưng điều này cũng xảy ra trong khi thử nghiệm trong Chrome. Bản sửa lỗi cũng hoạt động trong Chrome.

Tôi chưa phải làm điều này trong môi trường sản xuất và chưa nhận được bất kỳ báo cáo nào về việc mọi người không thể đăng nhập. Điều này dường như chỉ xảy ra sau khi làm cho cookie phiên được bảo mật. Nó không bao giờ xảy ra trong quá khứ khi họ không an toàn.


Cập nhật: điều này chỉ bắt đầu xảy ra sau khi chúng tôi thay đổi cookie phiên để đảm bảo an toàn. Tôi đã xác định rằng sự cố chính xác là do có hai hoặc nhiều cookie phiên trong trình duyệt có cùng đường dẫn và tên miền. Cái luôn luôn là vấn đề là cái có giá trị rỗng hoặc rỗng. Sau khi xóa cookie cụ thể đó, vấn đề đã được giải quyết. Tôi cũng đã thêm mã trong phương thức Global.asax.cs Sessin_Start để kiểm tra cookie trống này và nếu vậy thì đặt ngày hết hạn thành một cái gì đó trong quá khứ.
Matt L

2

trong trường hợp của tôi, đó là do tôi đã sửa đổi phiên sau khi chuyển hướng từ một cổng trong ứng dụng bên ngoài , vì vậy vì tôi đang sử dụng IP thay vì localhost trong url trang đó nên nó thực sự được coi là trang web khác nhau với các phiên khác nhau.

Tóm tắt

chú ý hơn nếu bạn đang gỡ lỗi một ứng dụng được lưu trữ trên IIS thay vì IIS express và trộn máy của bạn http: // Iphttp: // localhost trong các trang khác nhau


1

Vấn đề của tôi là với một ứng dụng Microsoft MediaRoom IPTV. Hóa ra các ứng dụng MPF MRML không hỗ trợ cookie; thay đổi để sử dụng các phiên vô dụng trong web.config đã giải quyết vấn đề của tôi

<sessionState cookieless="true"  />

Đây là một bài viết cũ thực sự về nó: ASP.NET Cookless


1

Tôi đang dùng .NET Core 2.1 và tôi biết rằng câu hỏi không phải là về Core. Tuy nhiên, internet đang thiếu và Google đã đưa tôi đến đây vì vậy hy vọng sẽ cứu được ai đó vài giờ.


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

Lưu ý rằng phiên viết và đọc hoạt động, nhưng dường như không có cookie nào được chuyển đến trình duyệt. Ít nhất tôi không thể tìm thấy tiêu đề "Set-Cookie" ở bất cứ đâu.



0

Hãy chắc chắn rằng bạn không có thời gian chờ phiên rất ngắn và cũng đảm bảo rằng nếu bạn đang sử dụng các phiên dựa trên cookie mà bạn đang chấp nhận phiên.

WebDeveloperToolbar của FireFox rất hữu ích vào những lúc như thế này vì bạn có thể thấy các cookie được đặt cho ứng dụng của mình.


2
Tôi đoán thời gian chờ phiên của tôi không được đặt dưới một giây. Nó thay đổi với mỗi lần nhấn F5 nhanh chóng.
Seb Nilsson

0

Đặt lại ID phiên có thể có nhiều nguyên nhân. Tuy nhiên, bất kỳ đề cập ở trên không liên quan đến vấn đề của tôi. Vì vậy, tôi sẽ mô tả nó để tham khảo trong tương lai.

Trong trường hợp của tôi, một phiên mới được tạo trên mỗi yêu cầu dẫn đến vòng lặp chuyển hướng vô hạn. Hành động chuyển hướng diễn ra trong sự kiện OnActionExecuting .

Ngoài ra tôi đã được thanh toán bù trừ tất cả các tiêu đề http (cũng trong OnActionExecuting kiện sử dụng Response.ClearHeaders phương pháp) để ngăn chặn các trang web bộ nhớ đệm về phía khách hàng. Nhưng phương pháp đó sẽ xóa tất cả các tiêu đề bao gồm thông tin về phiên của người dùng và do đó tất cả dữ liệu trong bộ lưu trữ Temp (mà tôi đang sử dụng sau này trong chương trình). Vì vậy, ngay cả việc thiết lập phiên mới trong sự kiện Session_Start cũng không giúp được gì.

Để giải quyết vấn đề của tôi, tôi đảm bảo không xóa các tiêu đề khi chuyển hướng xảy ra.

Hy vọng nó sẽ giúp được ai đó.


0

Tôi gặp vấn đề này một cách khác. Các bộ điều khiển có thuộc tính [SessionState(SessionStateBehavior.ReadOnly)]này đã đọc từ một phiên khác mặc dù tôi đã đặt giá trị trong phiên ban đầu khi khởi động ứng dụng. Tôi đã thêm giá trị phiên thông qua _layout.cshtml (có thể không phải là ý tưởng tốt nhất?)

Đó rõ ràng là ReadOnly gây ra sự cố bởi vì khi tôi xóa thuộc tính, phiên ban đầu (và SessionId) sẽ giữ nguyên trạng thái. Sử dụng giải pháp của Claudio / Microsoft đã sửa nó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.