现象:
1、客户能够 打开登陆界面,样式没有问题。
2、输入用户名密码后,已经开始跳转了,但是立即提示登陆超时。
分析:
1、客户能够 打开登陆界面,样式没有问题:
肯定不是样式出现问题,不是简单的界面问题了。
2、输入用户名密码后,已经开始跳转了,但是立即提示登陆超时
到了提示这一步就说明,说明已经登陆验证通过,并到了验证session是否存在的代码了,但是肯定是session,才会出现这个提示。
3、问题来了:就是创建了session,session马上就丢失了。按照客户的环境,我也试了chrome、ie9 、ie10等等,都是没有问题的。看来还是和浏览器本身没有关系,可能跟电脑环境、浏览器配置有关系,后来发现我这个怀疑是对的。
找到问题了,就得解决。首先我去网上找了一些资料。其中,有一个遇到的和我差不多。
有段话说的很有道理:
IT分享asp.net chrome浏览器无法使用session的原因和解决办法
因为Session是靠Cookie中保存的SessionId实现的,这样由于当前页面的Cookie不会传递给Flash请求的Upload.ashx,因此请求的文件发送到Upload.ashx就是一个新的Session了,当然这个Session就是没有登录的了。
我进一步查询了一下Session的机制:
Session是由应用服务器维持的一个服务器端的存储空间,用户在连接服务器时,会由服务器生成一个唯一的SessionID,用该SessionID 为标识符来存取服务器端的Session存储空间。而SessionID这一数据则是保存到客户端,用Cookie
Session是由应用服务器维持的一个服务器端的存储空间,用户在连接服务器时,会由服务器生成一个唯一的SessionID,用该SessionID 为标识符来存取服务器端的Session存储空间。而SessionID这一数据则是保存到客户端,用Cookie保存的,用户提交页面时,会将这一 SessionID提交到服务器端,来存取Session数据。这一过程,是不用开发人员干预的。所以一旦客户端禁用Cookie,那么Session也会失效。
我在chrome浏览器中启用cookie,就可以的登录了。禁用就无法登录。
看来真是这个问题了。
网上给出了一些解决方案,无外乎3种:
A.保存session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。
B.由于cookie可以被人为的禁止,必须有其它的机制以便在cookie被禁止时仍然能够把session id传递回服务器,经常采用的一种技术叫做URL重写,就是把session id附加在URL路径的后面,附加的方式也有两种,一种是作为URL路径的附加信息,另一种是作为查询字符串附加在URL后面。网络在整个交互过程中始终保持状态,就必须在每个客户端可能请求的路径后面都包含这个session id。
C.另一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。
在asp.net中就简单一些,修改一个web.config参数就行 :
仅仅只需要这样配置就可以了。进行这样的配置,我们将会发现我们的访问的网址变成了http://yourserver/folder/(session ID here)/default.aspx这种形式。服务器端的SessionID写在了浏览器栏里了,这样做会有一定的安全隐患--会话劫持,也就是说别人可以复制这个SessionID,从而以你的身份/会话访问网站。并且,如果我们在页面上写网站内部的超链接的时候,如Click,这样写,我们跳转之后的页面是以新的会话打开的,我们可以这样写 >Click ,通过Response的ApplyAppPathModifier方法来加入一个会话ID字符串到超链接里,这个方法采用一个表示 URL 的字符串作为参数,并且返回一个嵌入了会话信息的绝对 URL。并且这个方法可以使用在http链接跳转到https链接的情况下。
IT分享asp.net chrome浏览器无法使用session的原因和解决办法
就是很丑,我最后放弃这个方案。
但是还有一个问题,不知道大家注意没有:
就是为什么我的机器安装上chrome或者ie9之后,不用配置就可以登录使用session、cookie是启用的那?一开始我怀疑是安全软件的问题,但是这个一下子我就排除了,因为安全软件不手动配置也不会禁用cookie的。
只有一个可能就是操作系统本身安全性很高导致浏览器安装后无法使用cookie。后来有陆续反应问题的客户,发现这个猜测是对的:
出现问题电脑的操作系统是windows server版本的,win7 、win8、xp等操作系统安全系数是比较低的。尤其是默认浏览器IE是需要https验证的。
问题解决了。有时候程序出现的问题很简单,很表象,其实你自己的挖掘下去,发现还是很多道道的
补充:SWFUpload在Chrome、Firefox浏览器下session找不到的问题
SWFUpload是一个非常不错的异步上传组件,但是在Chrome、Firefox等浏览器下使用的时候会有问题。问题如下:为了防止跳过上传页面直 接向“接受SWFUpload上传的一般处理程序”(假如是Upload.ashx)发送请求造成WebShell漏洞,我的系统中对于 Upload.ashx进行了权限控制,只有登录用户才能进行上传。在IE下没问题,但是在Chrome下运行报错“用户未登录”。
经过搜索得知:因为SWFUpload是靠Flash进行上传的,Flash在IE下会把当前页面的Cookie发到Upload.ashx,但是Chrome、Firefox下则不会把当前页面的Cookie发到Upload.ashx。因为Session是靠Cookie中保存的SessionId实现的,这样由于当前页面的Cookie不会传递给Flash请求的Upload.ashx,因此请求的文件发送到Upload.ashx就是一个新的Session了,当然这个Session就是没有登录的了。
解决这个问题的思路也很简单,那就是手动把SessionId传递给服务器,再服务器端读出SessionId再加载Session。其实解决问题的办法 SWFUpload的Demo中已经给出了,那就是在SWFUpload的构造函数中设置post_params参数:
代码如下 | 复制代码 |
swfu = new SWFUpload({ post_params: { "ASPSESSID": "<%=Session.SessionID %>" } |
post_params中设定的键值对将会以Form表单的形式传递到Upload.ashx,也就是SWFUpload提供了为请求增加自定义请求参数的接口。
上面的代码把当前页面的SessionId写到ASPSESSID值中,当用户上传文件后,ASPSESSID就会传递到服务器上了,在Global.asax的Application_BeginRequest中添加如下代码:
代码如下 | 复制代码 |
var Request = HttpContext.Current.Request; var Response = HttpContext.Current.Response; 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 (Exception) { Response.StatusCode = 500; Response.Write("Error Initializing Session"); } |
其中UpdateCookie方法的定义如下:
代码如下 | 复制代码 |
static void UpdateCookie(string cookie_name, string cookie_value) { HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookie_name); if (cookie == null) { cookie = new HttpCookie(cookie_name); //SWFUpload 的Demo中给的代码有问题,需要加上cookie.Expires 设置才可以 cookie.Expires = DateTime.Now.AddYears(1); HttpContext.Current.Request.Cookies.Add(cookie); } cookie.Value = cookie_value; HttpContext.Current.Request.Cookies.Set(cookie); } |
原理:当用户请求到达ASP.Net引擎的时候Application_BeginRequest方法首先被调用,在方法中看客户端是否提交上来了ASPSESSID,如果有的话则把ASPSESSID的值写入Cookie(以"ASP.NET_SESSIONID"为Key,因为ASP.Net中SessionId就是保存在"ASP.NET_SESSIONID"为Key的Cookie中的),Application_BeginRequest方法后就可以从Cookie中读取到"ASP.NET_SESSIONID"的值还原出页面的Session了。
如果网站中还用到了Membership的FormsAuthentication验证,则还需要把AUTHID也按照SessionID的方法进行处理,这一点是其他讲到SWFUpload这个Bug处理的文章中没有提到的。
在SWFUpload的构造函数中设置post_params参数:
代码如下 | 复制代码 |
swfu = new SWFUpload({ upload_url: "/AdminHT/UploadArticleImg.ashx", post_params: { "ASPSESSID": "<%=Session.SessionID %>", "AUTHID" : "<%=Request.Cookies[FormsAuthentication.FormsCookieName].Value%>" }, |
在在Global.asax的Application_BeginRequest中添加如下代码:
代码如下 | 复制代码 |
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 (Exception) { Response.StatusCode = 500; Response.Write("Error Initializing Forms Authentication"); } |
什么要后面swfupload插件上传文件中session不支持问题了,因为小编觉得这个方法可以帮助我们解决net中session丢失问题。