有一个很老的web网站,一直使用 session 保存用户登录验证,一直也没什么问题,但近来频频有客户反映,登录后还是提示登录,就是一直的复重登录。
显示是客户一登录 session 就失效了,但具体 session 失效的原因,我们到这几天才找出来:原来有部分客户访问网站时,IP是不断变化的,基本上是一秒种就变一个IP的这种,主要是使用中国移动宽带的、使用了搜狗浏览器加速功能的、还有什么长城通宽带的等等,他们每一秒的IP都在变的。
显然,asp.net 的 session 一遇到IP变化就失效了,可能当初 asp.net 也没有考虑到用户的IP会不停的变吧。
现在惨了,因为是几年前的网站了,无法再在代码的基础上修改。不知道 iis 里面或者有没有其他办法设置,让客户的 IP 变了, session 不失效 ?
是不是路由的问题哦。之前看到一个类似的贴,说是路由的,我帮你找找,看看找得到否。
路由是一个原因,最实际原因客户的IP变了。所谓路由就是这个路由不稳定,造成不停的断线不停的重拨号,所以IP不停的变。但最终造成问题的,还是客户的IP变了。
如果用户用中国移动的宽带,然后服务器是双线,那就是用户每访问一次,IP就变一次,就这么变态。
@阿水乐园:
那只能坐等大神出现啦,我刚找了一番,没有找到,当初真该记下来的。- -!
惨,我觉得这只能在代码上解决。祝君好运
顺便MARK一下。
用Cookie,登陆后把Cookie存到客户电脑上,然后每次提交时检查不到Session就检查Cookie。
安全性要求不太高的话,使用Cookie,存加密的用户名密码,每次重新登录验证。
代码如果不能改,能不能外挂一个页面,通过FormsAuthentication的验证方法直接设置登陆成功
我以前也碰到过类似的问题,不过我是改代码解决的
protected void Application_BeginRequest(object sender, EventArgs e) { #region 重写session try { string session_param_name = "ASPSESSID"; string session_cookie_name = "ASP.NET_SessionId"; if (HttpContext.Current.Request.Form[session_param_name] != null) { UpdateCookie(session_cookie_name, HttpContext.Current.Request.Form[session_param_name]); } else if (HttpContext.Current.Request.QueryString[session_param_name] != null) { UpdateCookie(session_cookie_name, HttpContext.Current.Request.QueryString[session_param_name]); } } catch { } //此处是身份验证 try { string auth_param_name = "AUTHID"; string auth_cookie_name = FormsAuthentication.FormsCookieName; if (HttpContext.Current.Request.Form[auth_param_name] != null) { UpdateCookie(auth_cookie_name, HttpContext.Current.Request.Form[auth_param_name]); } else if (HttpContext.Current.Request.QueryString[auth_param_name] != null) { UpdateCookie(auth_cookie_name, HttpContext.Current.Request.QueryString[auth_param_name]); } } catch { } }
/// <summary> ///重新设定请求中的cookie值,将服务器端的session值赋值给它 /// </summary> /// <param name="cookie_name"></param> /// <param name="cookie_value"></param> private void UpdateCookie(string cookie_name, string cookie_value) { HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookie_name); if (null == cookie) { cookie = new HttpCookie(cookie_name); } cookie.Value = cookie_value; HttpContext.Current.Request.Cookies.Set(cookie); }
/// <summary> ///确定Session时间 Add By Author: Amityat Data:2012-03-01 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void Session_Start(object sender, EventArgs e) { base.Response.Cookies["ASP.NET_SessionId"].Value = base.Session.SessionID; base.Response.Cookies["ASP.NET_SessionId"].Expires = DateTime.Now.AddMonths(1); }
web.config中 一般用stateServer,流量大时用MemCached 需要注意的是,session放入进程时特别容易丢,所以我单独扩展了下
<!--<sessionState mode="StateServer" stateConnectionString="tcpip=localhost:42424" sqlConnectionString="data source=localhost;Trusted_Connection=yes" timeout="360"/>--> <sessionState cookieless="false" regenerateExpiredSessionId="true" mode="Custom" customProvider="MemcachedSessionProvider"> <providers> <add name="MemcachedSessionProvider" type="MemcachedProviders.Session.SessionStateProvider,MemcachedProviders" connectionStringName="ApplicationServices" dbType="none" writeExceptionsToEventLog="false" /> </providers> </sessionState>
高人终于出现了,这正是我期待的答案!这样原来的程序中的验证代码全部不需要变更,只加了一个 Application_BeginRequest 的 重写session ! 真是太好了,我立即更新,测试后即结贴给分,如还有什么问题我也会极时反馈给大家。非常感谢 !
你好,我用的是 sessionState mode="StateServer" stateConnectionString="tcpip=localhost:42424 ,不知道实际中这个的session容不容易丢失?
我对 <add name="MemcachedSessionProvider" type="MemcachedProviders.Session.SessionStateProvider,MemcachedProviders" connectionStringName="ApplicationServices" dbType="none" writeExceptionsToEventLog="false" 不理解, connectionStringName="ApplicationServices" 是写在哪里,如何写的呢 ?
@阿水乐园: sessionState Mode 中StateServer 相对InProc模式要稳定,
<sessionState cookieless="false" regenerateExpiredSessionId="true" mode="Custom" customProvider="MemcachedSessionProvider"> <providers> <add name="MemcachedSessionProvider" type="MemcachedProviders.Session.SessionStateProvider,MemcachedProviders" connectionStringName="ApplicationServices" dbType="none" writeExceptionsToEventLog="false" /> </providers> </sessionState>
这个就是自定义SessionState,这个需要MemCached 分布式缓存,需要你在服务器上安装配置好,如果你只是一台机器,建议你就用StateServer,我们网站并发大,是个服务器群所以就扩展了下,网上有好多这样的例子代码,就不列出来了,最主要的是你的Session,你要分析下这个到底是什么原因吃内存。是太碎片化了,还是存储对象太大了。