session.abandon(关于session验证用户登陆的问题)
亲爱的读者们,你是否对session.abandon和关于session验证用户登陆的问题的相关问题感到困惑?别担心,今天我将为你解答这些问题,让你对此有更清晰的认识。
session错误
我们可以使用 Session对象存储特定的用户会话所需的信息。当用户在应用程序的页之间跳转时,存储在 Session对象中的变量不会清除,而用户在应用程序中访问页面时,这些变量始终存在。当用户请求来自应用程序的 Web页时,如果该用户还没有会话,则 Web服务器将自动创建一个 Session对象。当会话过期或被放弃后,服务器将终止该会话。通过向客户程序发送唯一的 Cookie可以管理服务器上的 Session对象。当用户第一次请求 ASP应用程序中的某个页面时,ASP要检查 HTTP头信息,查看是否有在报文中有名为 ASPSESSIONID的 Cookie发送过来,如果有,则服务器会启动新的会话,并为该会话生成一个全局唯一的值,在把这个值作为新 ASPSESSIONID Cookie的值发送给客户端,正是使用这种 Cookie,可以访问存储在服务器上的属于客户程序的信息。Session对象最常见的作用就是存储用户的首选项。例如,如果用户指明不喜欢查看图形,就可以将该信息存储在 Session对象中。另外其还经常被用在鉴别客户身份的程序中。要注意的是,会话状态仅在支持 cookie的浏览器中保留,如果客户关闭了 Cookie选项,Session也就不能发挥作用了。一、属性 1、SessionID SessionID属性返回用户的会话标识。在创建会话时,服务器会为每一个会话生成一个单独的标识。会话标识以长整形数据类型返回。在很多情况下 SessionID可以用于 WEB页面注册统计。 2、TimeOut Timeout属性以分钟为单位为该应用程序的 Session对象指定超时时限。如果用户在该超时时限之内不刷新或请求网页,则该会话将终止。二、方法 Session对象仅有一个方法,就是 Abandon,Abandon方法删除所有存储在 Session对象中的对象并释放这些对象的源。如果您未明确地调用 Abandon方法,一旦会话超时,服务器将删除这些对象。当服务器处理完当前页时,下面示例将释放会话状态。<% Session.Abandon%>三、事件 Session对象有两个事件可用于在 Session对象启动和释放是运行过程。 1、Session_OnStart事件在服务器创建新会话时发生。服务器在执行请求的页之前先处理该脚本。Session_OnStart事件是设置会话期变量的最佳时机,因为在访问任何页之前都会先设置它们。尽管在 Session_OnStart事件包含 Redirect或 End方法调用的情况下 Session对象仍会保持,然而服务器将停止处理 Global.asa文件并触发 Session_OnStart事件的文件中的脚本。为了确保用户在打开某个特定的 Web页时始终启动一个会话,就可以在 Session_OnStart事件中调用 Redirect方法。当用户进入应用程序时,服务器将为用户创建一个会话并处理 Session_OnStart事件脚本。您可以将脚本包含在该事件中以便检查用户打开的页是不是启动页,如果不是,就指示用户调用 Response.Redirect方法启动网页。程序如下:< SCRIPT RUNAT=Server Language=VBScript> Sub Session_OnStart startPage="/MyApp/StartHere.asp" currentPage= Request.ServerVariables("SCRIPT_NAME") if strcomp(currentPage,startPage,1) then Response.Redirect(startPage) end if End Sub</SCRIPT>上述程序只能在支持 cookie的浏览器中运行。因为不支持 cookie的浏览器不能返回 SessionID cookie,所以,每当用户请求 Web页时,服务器都会创建一个新会话。这样,对于每个请求服务器都将处理 Session_OnStart脚本并将用户重定向到启动页中。 2、Session_OnEnd事件在会话被放弃或超时发生。关于使用 Session对象需要注意的事项 Application对象相近,请参照前文。会话可以通过以下三种方式启动: 1、一个新用户请求访问一个 URL,该 URL标识了某个应用程序中的.asp文件,并且该应用程序的 Global.asa文件包含 Session_OnStart过程。 2、用户在 Session对象中存储了一个值。 3、用户请求了一个应用程序的.asp文件,并且该应用程序的Global.asa文件使用< OBJECT>标签创建带有会话作用域的对象的实例。如果用户在指定时间内没有请求或刷新应用程序中的任何页,会话将自动结束。这段时间的默认值是 20分钟。可以通过在 Internet服务管理器中设置“应用程序选项”属性页中的“会话超时”属性改变应用程序的默认超时限制设置。应依据您的 Web应用程序的要求和服务器的内存空间来设置此值。例如,如果您希望浏览您的 Web应用程序的用户在每一页仅停留几分钟,就应该缩短会话的默认超时值。过长的会话超时值将导致打开的会话过多而耗尽您的服务器的内存资源。对于一个特定的会话,如果您想设置一个小于默认超时值的超时值,可以设置 Session对象的 Timeout属性。例如,下面这段脚本将超时值设置为 5分钟。<% Session.Timeout= 5%>当然你也可以设置一个大于默认设置的超时值,Session.Timeout属性决定超时值。你还可以通过 Session对象的 Abandon方法显式结束一个会话。例如,在表格中提供一个“退出”按钮,将按钮的 ACTION参数设置为包含下列命令的.asp文件的 URL。<% Session.Abandon%>
关于session验证用户登陆的问题
一.设置web.config相关选项
先启用窗体身份验证和默认登陆页,如下。
<authentication mode="Forms">
<forms loginUrl="default.aspx"></forms>
</authentication>
设置网站可以匿名访问,如下
<authorization>
<allow users="*"/>
</authorization>
然后设置跟目录下的admin目录拒绝匿名登陆,如下。注意这个小节在System.Web小节下面。
<location path="admin">
<system.web>
<authorization>
<deny users="?"></deny>
</authorization>
</system.web>
</location>
把http请求和发送的编码设置成GB2312,否则在取查询字符串的时候会有问题,如下。
<globalization requestEncoding="gb2312" responseEncoding="gb2312"/>
设置session超时时间为1分钟,并启用cookieless,如下。
<sessionState mode="InProc" cookieless="true" timeout="1"/>
为了启用页面跟踪,我们先启用每一页的trace,以便我们方便的调试,如下。
<trace enabled="true" requestLimit="1000" pageOutput="true" traceMode="SortByTime" localOnly="true"/>
二.设置Global.asax文件
处理Application_Start方法,实例化一个哈西表,然后保存在Cache里
protected void Application_Start(Object sender, EventArgs e)
{
Hashtable h=new Hashtable();
Context.Cache.Insert("online",h);
}
在Session_End方法里调用LogoutCache()方法,方法源码如下
///<summary>
///清除Cache里当前的用户,主要在Global.asax的Session_End方法和用户注销的方法里调用///</summary>
public void LogoutCache()
{
Hashtable h=(Hashtable)Context.Cache["online"];
if(h!=null)
{
if(h[Session.SessionID]!=null)
h.Remove(Session.SessionID);
Context.Cache["online"]=h;
}
}
三.设置相关的登陆和注销代码
登陆前调用PreventRepeatLogin()方法,这个方法可以防止用户重复登陆,如果上次用户登陆超时大于1分钟,也就是关闭了所有admin目录下的页面达到60秒以上,就认为上次登陆的用户超时,你就可以登陆了,如果不超过60秒,就会生成一个自定义异常。在Cache["online"]里保存了一个哈西表,哈西表的key是当前登陆用户的SessionID,而Value是一个ArrayList,这个ArrayList有两个元素,第一个是用户登陆的名字第二个元素是用户登陆的时间,然后在每个admin目录下的页刷新页面的时候会更新当前登陆用户的登陆时间,而只admin目录下有一个页打开着,即使不手工向服务器发送请求,也会自动发送一个请求更新登陆时间,下面我在页面基类里写了一个函数来做到这一点,其实这会增加服务器的负担,但在一定情况下也是一个可行的办法.
///<summary>
///防止用户重复登陆,在用户将要身份验证前使用
///</summary>
///<param name="name">要验证的用户名字</param>
private void PreventRepeatLogin(string name)
{
Hashtable h=(Hashtable)Cache["online"];
if(h!=null)
{
IDictionaryEnumerator e1=h.GetEnumerator();
bool flag=false;
while(e1.MoveNext())
{
if((string)((ArrayList)e1.Value)[0]==name)
{
flag=true;
break;
}
}
if(flag)
{
TimeSpan ts=System.DateTime.Now.Subtract(Convert.ToDateTime(((ArrayList)e1.Value)[1]));
if(ts.TotalSeconds<60)
throw new oa.cls.MyException("对不起,你输入的账户正在被使用中,如果你是这个账户的真正主人,请在下次登陆时及时的更改你的密码,因为你的密码极有可能被盗窃了!");
else
h.Remove(e1.Key);
}
}
else
{
h=new Hashtable();
}
ArrayList al=new ArrayList();
al.Add(name);
al.Add(System.DateTime.Now);
h[Session.SessionID]=al;
if(Cache["online"]==null)
{
Context.Cache.Insert("online",h);
}else
Cache["Online"]=h;
}
用户注销的时候调用上面提到LogoutCache()方法
四.设置admin目录下的的所有页面的基类
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Collections;
namespace oa.cls
{
public class MyBasePage: System.Web.UI.Page
{
///<summary>
///获取本页是否在受保护目录,我这里整个程序在OA的虚拟目录下,受保护的目录是admin目录
///</summary>
protected bool IsAdminDir
{
get
{
return Request.FilePath.IndexOf("/oa/admin")==0;
}
}
///<summary>
///防止session超时,如果超时就注销身份验证并提示和转向到网站默认页
///</summary>
private void PreventSessionTimeout()
{
if(!this.IsAdminDir) return;
if(Session["User_Name"]==null&&this.IsAdminDir)
{
System.Web.Security.FormsAuthentication.SignOut();
this.Alert("登陆超时",Request.ApplicationPath
Asp.Net处理Session失效解决方案
检查ASP NET Session是否失效是否超时默认是分钟设置的方法是Session TimeOut=;或者您可以设置到更高这个数值的单位是分钟大家视情况而定
检查代码有无Session Abandon()之类的一旦调用 Abandon方法当前会话不再有效同时会启动新的会话
ASP NET中使用了ACCESS数据库而且数据库是放在bin目录中的解决方法是不要放会更新的文件在BIN目录中
从同一个页面传到另一个页面才能延续同一个session也就是说session不可跨域同时客户端一关闭浏览器或一关闭浏览页 Session也消失了再次访问时又会创建新的Session但还会在服务器上存活等待超时只是调用不到了另外比如在第一个页面置了SESSION然后REDIRECT去第二个页面解决方法是在REDIRECT中设置endResponse为FALSE
Iframe丢Session的原因 session是客户端和服务器端共同认证的客户端存储标识通过附加在页面的头发送给服务器端服务器进行识别如果符合条件就可以获得相应的session操作权
但如果页面是来自框架的而框架的父页和框架不是一个站点的话客户端默认是禁止向页面附加头信息的这样服务器端就无法识别客户端框架里面的页面自然不能操作Session解决办法: Response AddHeader( P P CP=CAO PSA OUR)或者在Window服务中将 State Service启动
有些杀病毒软件会去扫描您的Web Config文件那时Session肯定掉这是微软的说法解决办法:使杀病毒软件屏蔽扫描Web Config文件(程序运行时自己也不要去编辑它)
ASP NET默认配置下 Session莫名丢失的原因及解决办法
正常操作情况下Session会无故丢失因为程序是在不停的***作排除Session超时的可能另外 Session超时时间被设定成分钟不会这么快就超时的
现在我就把原因和解决办法写出来
ASP NET Session失效的原因
由于程序是默认配置所以Web Config文件中关于Session的设定如下
<sessionStatemode= InProc stateConnectionString= tcpip=:
sqlConnectionString= datasource=;Trusted_Connection=yes cookieless= true
timeout=/>
我们会发现sessionState标签中有个属性mode它可以有种取值 InProc StateServer?SQLServer(大小写敏感)默认情况下是InProc也就是将Session保存在进程内(IIS是aspnet_wp exe而IIS是W wp exe)这个进程不稳定在某些事件发生时进程会重起所以造成了存储在该进程内的Session丢失
哪些情况下该进程会重起呢?微软的一篇文章告诉了我们
配置文件中processModel标签的memoryLimit属性
Global asax或者nfig文件被更改
Bin文件夹中的Web程序(DLL)被修改
杀毒软件扫描了一nfig文件
更多的信息请参考PRB: Session variables are lost intermittently in applications
ASP NET Session失效的解决办法
前面说到的sessionState标签中mode属性可以有三个取值除了InProc之外还可以为StateServer SQLServer这两种存Session的方法都是进程外的所以当aspnet_wp exe重起的时候不会影响到Session
现在请将mode设定为StateServer StateServer是本机的一个服务可以在系统服务里看到服务名为 State Service的服务默认情况是不启动的当我们设定mode为StateServer之后请手工将该服务启动
这样我们就能利用本机的StateService来存储Session了除非电脑重启或者StateService崩掉否则Session是不会丢的(因Session超时被丢弃是正常的)
除此之外我们还可以将Session通过其他电脑的StateService来保存具体的修改是这样的同样还在sessionState标签中有个stateConnectionString= tcpip=:属性其中有个ip地址默认为本机()你可以将其改成你所知的运行了StateService服务的电脑IP这样就可以实现位于不同电脑上的程序互通Session了
如果你有更高的要求需要在服务期重启时Session也不丢失可以考虑将mode设定成SQLServer同样需要修改sqlConnectionString属性关于使用SQLServer保存Session的操作在使用StateServer或者SQLServer存储Session时所有需要保存到Session的对象除了基本数据类型(默认的数据类型如int string等)外都必须序列化只需将[Serializable]标签放到要序列化的类前就可以了
如
[Serializable]
publicclassMyClass
{
lishixinzhi/Article/program/net/201311/12478文章到此结束,如果本次分享的session.abandon和关于session验证用户登陆的问题的问题解决了您的问题,那么我们由衷的感到高兴!