代码之家  ›  专栏  ›  技术社区  ›  Seb Nilsson

ASP.NET:session.sessionid请求之间的更改

  •  126
  • Seb Nilsson  · 技术社区  · 15 年前

    为什么物业 会话ID 会话 -是否在请求之间更改ASP.NET页中的对象?

    我有一个这样的页面:

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

    每次我点击F5,输出都在不断变化,与浏览器无关。

    13 回复  |  直到 6 年前
        1
  •  200
  •   Claudio Redi    9 年前

    这就是原因

    使用基于cookie的会话状态时,在使用会话对象之前,ASP.NET不会为会话数据分配存储。因此,在访问会话对象之前,会为每个页面请求生成一个新的会话ID。如果应用程序需要整个会话的静态会话ID,则可以在应用程序的global.asax文件中实现会话启动方法,并将数据存储在会话对象中以修复会话ID,也可以在应用程序的其他部分中使用代码显式地将数据存储在会话对象中。

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

    因此,基本上,除非您在后端访问会话对象,否则每个请求都将生成一个新的sessionid。

    编辑

    此代码必须添加到global.asax文件中。它向会话对象添加一个条目,以便您修复会话,直到其过期。

    protected void Session_Start(Object sender, EventArgs e) 
    {
        Session["init"] = 0;
    }
    
        2
  •  84
  •   Neville Cook    13 年前

    还有另一个更阴险的原因,即即使会话对象已被初始化(如cladudio所示),也可能发生这种情况。

    在web.config中,如果 <httpCookies> 设置为的条目 requireSSL="true" 但实际上您并没有使用HTTPS:对于特定的请求,会话cookie不会被发送(或者可能不会返回,我不确定是哪个),这意味着您最终会为每个请求创建一个全新的会话。

    我发现这是一个困难的方法,在源代码管理中的几个提交之间来回花费几个小时,直到我发现什么特定的更改破坏了我的应用程序。

        3
  •  5
  •   Kniganapolke    12 年前

    在我的例子中,我发现会话cookie有一个 领域 包括在内 www. 前缀,当我请求不带 www. .
    添加 www. 到URL立即解决了问题。后来我把cookie的域改为 .mysite.com 而不是 www.mysite.com .

        4
  •  3
  •   Reid    12 年前

    使用Neville的答案(在web.config中删除requiressl=true) 稍微修改一下Joel Etherton的代码,这里的代码应该处理一个同时在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
  •  2
  •   R. Aaron Zupancic    11 年前

    另一种可能导致sessionid在请求之间发生更改,即使定义了会话启动和/或初始化了会话,也可能是URL主机名包含无效字符(如下划线)。我相信这是IE特定的(未验证),但是如果您的URL是,比如, http://server_name/app ,则IE将阻止所有cookie,并且在请求之间无法访问会话信息。

    实际上,每个请求都将在服务器上启动一个单独的会话,因此,如果您的页面包含多个图像、脚本标记等,那么每个GET请求都将导致服务器上的不同会话。

    更多信息: http://support.microsoft.com/kb/316112

        6
  •  1
  •   denvercoder9    11 年前

    我的问题是Microsoft MediaRoom IPTV应用程序。结果证明MPF MRML应用程序不支持cookie;在web.config中更改为使用无cookie会话解决了我的问题。

    <sessionState cookieless="true"  />
    

    这是一篇非常古老的文章: Cookieless ASP.NET

        7
  •  1
  •   josh    9 年前

    我的问题是我们在web.config中有这个集合

    <httpcookies httponlycookies=“true”requiressl=“true”/>

    这意味着在非SSL(默认)中进行调试时,auth cookie不会被发送回服务器。这意味着服务器将为每个请求向客户端发送一个新的身份验证cookie(带有新会话)。

    修复方法是在web.config中将requiressl设置为false,在web.release.config中将其设置为true,或者在调试时打开ssl:。

    这意味着在非SSL(默认)中进行调试时,auth cookie不会被发送回服务器。这意味着服务器将为每个请求向客户机发送一个新的身份验证cookie(带有一个新会话)。

    修复方法是在web.config中将requiressl设置为false,在web.release.config中将其设置为true,或者在调试时打开ssl:

    turn on SSL

        8
  •  1
  •   Matt L    8 年前

    在我的例子中,这在我的开发和测试环境中发生了很多。在尝试了上述所有解决方案但没有任何成功之后,我发现我可以通过删除所有会话cookie来解决此问题。Web开发人员扩展使这一操作非常容易。我主要使用火狐进行测试和开发,但在Chrome中测试时也会发生这种情况。修复也在铬合金中起作用。

    我还没有在生产环境中这样做,也没有收到任何人无法登录的报告。这似乎也是在会话cookie安全之后才发生的。以前他们不安全的时候从来没有发生过。

        9
  •  1
  •   Iman    7 年前

    在我的案例中,这是因为我正在修改会话 从外部应用程序中的网关重定向后 因此,因为我在本地主机上使用IP,而在该页面的URL中,它实际上被认为是不同的网站,具有不同的会话。

    综上所述

    如果要在IIS上调试托管应用程序而不是在IIS Express上调试并混合您的计算机,请更加注意。 http://Ip http://localhost 在不同的页面中

        10
  •  0
  •   Mitchel Sellers    15 年前

    确保您没有非常短的会话超时,并且确保如果您使用的是基于cookie的会话,那么您正在接受该会话。

    Firefox Webdevelopertoolbar在这种时候很有用,因为您可以看到为您的应用程序设置的cookie。

        11
  •  0
  •   user3253726    11 年前

    会话ID重置可能有许多原因。不过,上面提到的和我的问题无关。所以我将对其进行描述,以备将来参考。

    在我的例子中,对每个请求创建的新会话会导致无限的重定向循环。重定向操作发生在 操作执行 事件。

    另外,我已经清除了所有HTTP头(也在 操作执行 事件使用 响应.clearheaders 方法)以防止在客户端缓存站点。但该方法清除所有头文件,包括有关用户会话的信息,从而清除临时存储器中的所有数据(稍后在程序中使用)。所以即使在会话启动事件中设置新会话也没有帮助。

    为了解决我的问题,我确保在重定向发生时不删除头。

    希望它能帮助别人。

        12
  •  0
  •   goku_da_master    9 年前

    我以另一种方式处理这个问题。具有此属性的控制器 [SessionState(SessionStateBehavior.ReadOnly)] 即使在应用启动时在原始会话中设置了一个值,也在从其他会话读取。我是通过ou layout.cshtml添加会话值的(也许不是最好的主意?)

    显然是只读导致了这个问题,因为当我删除属性时,原始会话(和sessionid)将保持不变。使用Claudio/Microsoft的解决方案修复了它。

        13
  •  0
  •   krivar    6 年前

    我在.NET核心2.1上,我很清楚这个问题不是关于核心的。然而,互联网是缺乏的,谷歌把我带到这里,希望能为某人节省几个小时。


    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”标题。