有关session链接
有关session丢失的解决方案:
1、http://m.2cto.com/kf/201702/593964.html
2、http://www.blogjava.net/Hopes/articles/385313.html
ASP.NET 使用mode=”InProc”方式保存Session老是丢失,无奈改成StateServer 模式。
session是工作在你的应用程序进程中的。asp.net进程、iis往往会在20分钟之后重启相关的应用程序,缓冲池满了(例如100个之后)也会重启,各种进程保护措施都会随时重新启动,因此InProc方式丢失session是很正常的事。csdn上明确告诉了这种模式只能保存“易失的、暂时的 ”变量,这是cache没有之前的一种解决方案。而长期保持的数据就要保存在外部数据源中。状态服务器就是一种进程外的数据源。
StateServer 模式的实质是,把Session 存放在一个单独的进程里,此进程独立于 aspnet_wp.exe 或 w3wp.exe 。启用此服务后,在“任务管理器”中可以看到一个名为 aspnet_state.exe 的进程,下面开始说明一下设置的具体步骤:
1、 修改注册表(关键步骤,如下图)
运行 regedit → 打开注册表 → 找到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state \Parameters 节点 → 将 AllowRemoteConnection 的键值设置成“1”(1 为允许远程电脑的连接,0 代表禁止)→ 设置 Port (端口号)
注意事项:
a)、若ASP.NET State Service 正在运行,修改注册表内容后,则需要重新启动该服务
b)、注意端口号的键值是以十六进制储存的,可以使用十进制进行修改,42424 是默认的端口
c)、AllowRemoteConnection 的键值设置成“1”后,意味着允许远程电脑的连接,也就是说只要知道你的服务端口,就可享用你的ASP.NET State Service,即把 Session 存放在你的电脑进程内,因此请大家慎用;键值为“0”时,仅有stateConnectionString 为“tcpip=localhost: 42424”与“tcpip=127.0.0.1:42424”的情况,方可使用ASP.NET State Service
2、 开启 ASP.NET State Service
右键点击“我的电脑”→ 管理 → 服务与应用程序 → 服务 → 双击“ASP.NET State Service” → 启动(可设为“自动”)
说明:只要安装了 .Net Framework ,都拥有此服务。
3、 更改 Web.config
打开 Web.config → 找到
<sessionState
mode=”InProc”
stateConnectionString=”tcpip=127.0.0.1:42424″
sqlConnectionString=”data source=127.0.0.1;Trusted_Connection=yes”
cookieless=”false”
timeout=”20″ />
→ 将其改为以下内容
<sessionState mode=”StateServer” stateConnectionString=”tcpip=192.168.0.2:42424″ timeout=”20″ />
注意事项:
1、timeout=”20″为Session 20分钟超时
2、IP 地址(可以是远程计算机 IP、计算机名称、域名)与端口号,端口号需与ASP.NET State Service 的服务端口一致
3、http://m.2cto.com/kf/201702/593964.html
4、http://m.2cto.com/kf/201702/593964.html
5、http://m.2cto.com/kf/201702/593964.html
理解Session的几种模式
一、写在前面
我们在使用ASP.NET开发的过程中,有时会进行数据存储以实现请求前后的状态保持(HTTP是无状态保持的协议),而Session作为一种快速简单易于实现的方式被我们经常使用,当然如果出于性能方面的考量,我们还是不建议往Seesion中塞入更多的东西,最好是不用Session。
还有一点需要说明的是,Session实现的本质是在客户端产生一个SessionId,具体的数据存储在服务器端,客户端通过SessionId来获取服务器端的具体数据,那这个SeesionId是怎么保存在客户端以及又是以什么方式来传给服务器的呢?服务器端又是以什么方式保存Session的这些数据的呢?各种方式的优缺点又是什么?这就是本篇随笔想要记录的内容。
二、配置方式(Custom自定义模式博主未介绍,自行百度)
<sessionState mode="Off|InProc|StateServer|SQLServer|Custom"
cookieless="true|false"
timeout="number of minutes"
stateConnectionString="tcpip=server:port"
sqlConnectionString="sql connection string"
stateNetworkTimeout="number of seconds" />
上面是Session在Web.config的配置方式,下面对各个节点做一些简单的介绍
mode(设置将服务器的Session信息存储到哪里)
- Off表示设置为不使用Session功能;
- InProc表示将Session存储在进程内,这也是ASP中的存储方式,这是默认值;
- StateServer表示将Session存储在独立的状态服务即ASP.NET State Service中;
- SQLServer表示将Session存储在SQL Server。
cookieless(设置客户端的Session信息存储到哪里)
- true表示使用Cookieless模式(这表明SessionId将不再使用Cookie存储了,而是将其通过URL存储);
- false表示使用Cookie模式,这是默认值。
从上面的设置配置中我们也可以发现Session和Cookie的关系:
- 首先Session在客户端的实现肯定是SessionId;
- 默认这个SessionId是通过Cookie存储的(比较安全);
- 当然也可以通过URL来进行存储,这样Session和Cookie就没有关系了,但是此种方式由于受URL长度限制以及明文传送导致不安全而不被推荐使用。
timeout
Session过期时间设置,默认为20分钟。
stateConnectionString
如果设置将Session信息存储在State Server中时,则需要此配置字符串表明服务器名称和端口。
sqlConnectionString
如果设置将Session信息存储在SQL Server中,需此配置,表明数据库的连接字符串,同时stateNetworkTimeout表明经过多少秒空闲后,断开Web服务器与存储状态信息的服务器的TCP/IP连接的。默认值是10秒钟。
三、Session服务器端配置
1. InProc
顾名思义,此种模式表示Session将会被保存在内存中,确切地说是保存在工作者进程中,对于IIS 5而言是aspnet_wp.exe,对于IIS 6而言是w3wp.exe,设置方式如下(Web.config)
<sessionState mode="InProc" cookieless="false" timeout="20"/>
由于是直接保存在进程中,所以性能最好,但是经常会发生Session信息丢失,常见的导致进程重启的可能情况为:
- 配置文件中processModel标签的memoryLimit属性;
- Global.asax或者Web.config文件被更改;
- Bin文件夹中的Web程序(DLL)被修改;
- 杀毒软件扫描了一些.config文件;
- 系统资源紧张进行资源回收导致IIS进程崩溃或重启等。
- 更多信息请参阅http://support.microsoft.com/kb/316148
2. State Server
此种方式是将Session信息存储在其它的进程中而不是IIS中,这样就可以避免因IIS进程崩溃或重启而导致的Session信息丢失。但是此种方式要求保存在Session的信息必须序列化,然后从Session中获取的时候也要反序列化,这就导致性能有略微的损失。
<sessionState mode="StateServer" cookieless="false" timeout="20"/>
StateServer是本机的一个服务,可以在系统服务里看到服务名为ASP.NET State Service的服务,默认情况是不启动的。当我们设定mode为StateServer之后,请把该服务的启动模式设置为自动(这样下次服务就可以随机器而启动)并手工将该服务启动运行。这样,我们就能利用本机的StateService来存储Session了,除非电脑重启或者StateService崩掉,否则Session是不会丢的。
<sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" cookieless="false" timeout="20"/>
此种配置和上面是一样的(多了个stateConnectionString,换句话说127.0.0.1是默认本机IP,42424默认是该服务的访问端口号,写不写效果是一样的),都表示StateServer是在本机(注:StateServer模式是支持远程主机服务的,配置类似与下面)
<sessionState mode="StateServer" stateConnectionString="tcpip=10.7.10.87:42424" cookieless="false" timeout="20"/>
注:如果在启动ASP.NET State Service服务时遇到问题0x8007277a 即无法启动或初始化,请尝试在命令行(CMD)中输入netsh winsock reset(有可能是winsock的问题,所以需reset一下)
3. SQL Server
此种方式是把Session信息保存在SQL Server的数据库中,也需要序列化,性能有较大损失,但是Session一般不会发生丢失的情况,除非SQL Server宕机。而且此种方式也可以实现在Web Farm中的Session信息共享(上面两种方式都不可以)。
<sessionState mode="SQLServer" sqlConnectionString ="data source=10.7.11.114; user id=session_user; password=Session@Pwd" timeout="20" />
3.1 安装ASPState数据库
在使用之前,我们要安装配置对应的数据库,而微软给我们提供了一整套方案(你也可以选择使用自己的数据库或自己实现配置和管理)。ASP.NET 2.0版本后微软提供了aspnet_regsql.exe工具可以方便的配置Session数据库,该工具位于 Web 服务器上的"系统根目录\Microsoft.NET\Framework\版本号"文件夹中.
使用举例:
aspnet_regsql.exe -S . -U session_user -P Session@Pwd -ssadd -sstype p
-S参数:
表示数据库实例名称. 可以用"."表示本机,你也可以指定机器,如10.7.11.110等
-U和-P参数:
表示用户名和密码.
-E参数:
可以再-U –P 与 -E中选择一组. –E表示以当前系统用户通过windows身份验证登录数据库, -U -P则是使用SqlServer用户登录数据库.
-ssadd / –ssremove 参数:
-ssadd表示是添加Session数据库, -ssremove表示移除Session数据库.
sstype 参数:
选项
说明
t
将会话数据存储到 SQL Server tempdb 数据库中。这是默认设置。如果将会话数据存储到 tempdb 数据库中,则在重新启动 SQL Server 时将丢失会话数据。
p
将会话数据存储到 ASPState 数据库中,而不是存储到 tempdb 数据库中。
c
将会话数据存储到自定义数据库中。如果指定 c 选项,则还必须使用 -d 选项包括自定义数据库的名称。
注意:如果sstype为t,则在下面的用户权限赋予中要授予对tempdb的dbowner权限,否则将无法操作数据库。
3.2 建立连接数据库 ASPState 的用户,并为此用户授权
运行 SQL Server 的企业管理器 → 展开数据库的安全性 → 右击“登录” → 新建“登录” → 输入“名称” → 选择 “SQL Server 身份验证” → 输入“密码” → 指定“数据库” → 点击“数据库访问” → 勾选 “ASPState” → 选中“db_owner”角色 → 点击“确定” → 再一次输入“密码” → 点击“确定” 后即可建立 ASPState 的用户,下面用命令实现:
--新建数据库帐号 SessionStateUser ,默认登录 ASPState
EXEC sp_addlogin 'SessionStateUser', '123456', 'ASPState'
use ASPState --切换 DataBase
--将 SessionStateUser 授予 db_owner 的权限
exec sp_adduser 'SessionStateUser', 'SessionUser' ,'db_owner'
3.3 启动SQL Server Agent
自动运行Job ASPState_Job_DeleteExpiredSessions删除过期的Session,否则数据库中的数据将一直增长。
四、Session客户端配置
再次说明,Session的实现分为两个部分:客户端和服务器端,其中客户端负责产生SessionId,服务器端负责保存具体的内容,这儿所说的Session客户端配置其实是想说说关于SessionId的一些东西。
1. Session在客户端是如何实现的?
前面已经说过,Session在客户端是通过产生SessionId来实现的,至于这个SessionId又是通过什么方式回传之服务器从而获得具体的Session内容,前面也略有说明,两种方式:Cookie和Url,由于Url的方式会导致安全性问题,所以现在一般已不再使用此种方式。
当系统是用Session的时候,系统将自动在客户端产生一个Cookie,名称为ASP.NET_SessionId,为了便于区别,我们暂且将此Cookie称为Session Cookie
2. Session Cookie何时失效?
和一般的Cookie一样,默认是保存在浏览器的内存中,当浏览器关闭时失效,如果想此Cookie保存在本地磁盘,可通过设置其Expires属性来达到,这种方式现在也被广泛应用于网站的登录,即用户在登录的时候选择记住我或保持登录一段时间,这样当用户下次再次访问的时候就无需再次输入用户名密码从而达到快速访问的目的
HttpCookie httpCookie = new HttpCookie("ASP.NET_SessionId", Request.Cookies["ASP.NET_SessionId"].Value);
httpCookie.Expires = DateTime.Now.AddMinutes(20);
Response.Cookies.Add(httpCookie);
if (!string.IsNullOrEmpty(Request.Cookies["ASP.NET_SessionId"].Value))
{
//...处理相关登录验证等信息
Response.Redirect("Default.aspx?UserName=" + loginUser.UserName + "");
}
3. Session Cookie失效时Session失效吗?
答案当然是否定的,记住:Session Cookie和Session的失效没有任何必然的联系,因为它们失效的基准或者条件根本不一样,Session Cookie的失效时间取决于客服端Cookie的失效时间,如果是保存在浏览器中,那么关闭浏览器Session Cookie就将失效,否则如果保存在本地磁盘,则取决于该Session Cookie设置的过期时间;而服务器端的Session是保存在服务器端的,它的失效与否与其服务器端的设置和Session的过期时间有关(下面的讨论将忽略过期时间这个因数,你懂的),如果是InProc方式,那么当承载的IIS进程如果奔溃或重启等都会丢失;如果是State Server,同样如果这个Service宕掉,那Session也会丢失;而如果是SQL Server,则会写入数据库,如果你不删除它,它甚至可以一直存在而永不丢失(事实是SQL Server Agent会自动运行一个Job删除过期的Session);而当如果我们使用自定义的数据库来保存Session时,你将获得充分的控制。
4. Session Cookie何时产生?刷新页面其值会改变吗?
牢记一点,只有当使用Session的时候才会产生Session Cookie。你也许会反问那为什么当配置Session模式为SQLServer时,就算没有使用Session,也可以获得ASP.NET_SessionId的值,即在Page_Load的时候执行方法Response.Write(Request.Cookies["ASP.NET_SessionId"].Value),会输出值,我的猜测是虽然你可以获得ASP.NET_SessionId值,但实际上并没有真正产生Session Cookie,因为此时当我试图通过HttpWatch(下面介绍的工具)来查看此Session Cookie的时候根本查不到,当然这也只是我的个人猜测而已,至于具体的内部机制还是不甚了解。
当没有使用Session的时候刷新页面Session Cookie的值会变化吗?答案是会的,测试方法如上,设置Session模式为SQLServer,在Page_Load的时候输出Session Cookie的值,然后一直F5页面即可,你会看到其值一直在变化,直到在代码中明确地使用Session后便不再变化。
public partial class Login : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Response.Write(Request.Cookies["ASP.NET_SessionId"].Value);
}
protected void tbnLogin_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(this.txtUserName.ToString()) && !string.IsNullOrEmpty(this.txtPassword.ToString()))
{
LoginUser loginUser = new LoginUser();
loginUser.UserId = Guid.NewGuid().ToString("N");
loginUser.UserName = this.txtUserName.Text;
loginUser.UserPassword = this.txtPassword.Text;
Session["LoginUser"] = loginUser;
}
}
}
5. Session Cookie如何查看
如果设置了Session Cookie的过期时间,则此Session Cookie会保存在本地磁盘,一般是在目录C:\Documents and Settings\user\Local Settings\Temporary Internet Files,此目录可手工设置(Internet选项->常规->浏览历史记录中的"设置"选项->Internet临时文件的"查看文件"选项)。
如果没有设置过期时间,则Session Cookie默认是保存在浏览器内存中的,Chrome浏览器默认支持查看Cookie,具体步骤如下:Tools - > Settings ->Show Advanced Settings -> Privacy -> Content Settings -> Cookies -> All cookies and site data,不过坑爹的是它只支持查看和删除,不支持修改,如果你想修改的话,我们只能通过第三方插件来完成https://chrome.google.com/webstore/detail/fngmhnnpilhplaeedifhccceomclgfbg(Chrome Web Store浏览下载安装即可)
如果你使用的是IE浏览器,你也要通过安装插件HttpWatch来查看(Firefox也适用)
五、Session的其它相关问题
1. 如何捕获Global.asax中的Session_End()事件?
- Session的服务器端模式必须配置为InProc,其它两种模式(State Server或SQL Server)无法获得Session_End事件;
- Session过期时,此事件才会发生,与用户是否关闭浏览器无关(关闭浏览器唯一可能的影响是此Session在客户端部分产生的Cookie失效,而服务器端Session继续存在,而且此时Cookie失效的前提也是把Cookie保存在浏览器中)
另请注意:在Session_End()中如果试图去使用Response或Request都是错误的,因为它们此时都已失效,不过你可以用记录log的方法来获取session失效的相关信息。
2. 如果提高客户端Session Cookie的安全性?
指定HttpCookie对象的HttpOnly属性为true,此属性用于标识一个Cookie是否可通过客户端脚本访问,true为可以,false为不可以,默认为false。设定的方式有两种:编程或配置文件。注意此属性并不能完全阻止客户端在本地获取cookies(上面已经介绍过如果获取此session cookie),但是可以增加通过脚本直接获取的难度。另外,Microsoft Internet Explorer 版本 6 Service Pack 1 和更高版本支持 Cookie 属性 HttpOnly。
HttpCookie sessionCookie = new HttpCookie("ASP.NET_SessionId"); sessionCookie.HttpOnly = true; <httpCookies httpOnlyCookies="true" />
对Cookies实行加密和用https传输:
HttpCookie sessionCookie = new HttpCookie("ASP.NET_SessionId"); sessionCookie.HttpOnly = true; sessionCookie.Secure = true; <httpCookies httpOnlyCookies="true" requireSSL="true" />
原文链接:http://www.cnblogs.com/panchunting/archive/2012/06/25/ASPNET\_Session\_Mode.html
1. sessionState的几种mode模式
在ASP.NET中Session的sessionState的4中mode模式:Off、InProc、StateServer及SqlServer。
<sessionState mode="Off|InProc|StateServer|SQLServer"
cookieless="true|false"
timeout="number of minutes"
stateConnectionString="tcpip=server:port"
sqlConnectionString="sql connection string"
stateNetworkTimeout="number of seconds" />
2. Off模式
<sessionState mode="Off"></sessionState>
关闭模式,即不需要使用Session。
单个页面关闭Session:
<%@ Page EnableSessionState="false" %>
3. InProc模式(缺省模式)
<sessionState mode="InProc" cookieless="false" timeout="20"></sessionState>
mode设置为"InProc"时,Session直接存储在IIS进程中。
优点:获取session状态的速度快
缺点:易丢失
mode为InProc可能造成Session丢失的情况:
1>. ASP.NET进程(aspnet_wp.exe)、IIS进程(w3wp.exe)默认的20分钟重启应用程序;
2>. 缓冲池填满后重启;
3>. 进程保护措施重启。
4. StateServer模式
mode设置为"StateServer"时,Session 存储在单独的内存缓冲区中,再由单独一台服务器上运行的ASP.NET State Service(aspnet_state.exe)来控制这个缓冲区。
优点:session状态单独存储在一个进程中,不会因为iis或者应用的重启而丢失状态。
缺点:
1>. 由于是两个不同的进程,获取Session数据比InProc慢;
2>. Session数据存储在内存中,重启ASP.NET State Service服务,Session数据将丢失。
<sessionState mode="StateServer" stateConnectionString="tcpip=tcpip=127.0.0.1:42424" cookieless="false" timeout="20"></sessionState>
以上设置的ASP.NET State Service在127.0.0.1的42424端口(默认端口)上运行,要在服务器上改变端口,可编辑HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters注册表项中的Port值。(打开注册表方式:运行 regedit)
mode设置为"StateServer"需要注意:
1>. 启动ASP.NET State Service;
2>. 如果stateConnectionString的值不是127.0.0.1或者localhost等代表本地地址的值,需要修改注册表:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state \Parameters 节点 → 将 AllowRemoteConnection 的键值设置成“1”(1 为允许远程电脑的连接,0 代表禁止)→ 设置 Port (端口号)
5. SqlServer模式
mode设置为"SqlServer"时,Session存储在SQL Server数据库中持久化保持,ASP.NET尝试将会话数据存储到由sqlConnectionString属性(其中包含数据源以及登录服务器所需的安全凭证)指定的SQL Server中。可应用场景:网络负载均衡(NLB)环境。
设置SqlServer模式步骤:
1>. 配置SQL erver创建ASPState数据库
创建ASPState数据库,运行C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallSqlState.sql,可以通过SQL查询分析器来执行语句,也可以使用sqlcmd来执行。
sqlcmd -S [server name] -U [user] -P [password] -i C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallSqlState.sql
此时SQLServer会创建数据库ASPState,但是没有表。
若创建ASPState数据库后要删除,可以运行C:\Windows\Microsoft.NET\Framework\v4.0.30319\UninstallSqlState.sql,但要先停止w3svc进程。
net stop w3svc
2>. ASPState创建表
aspnet_regsql.exe -ssadd -sstype p -S [server name] -U [user] -P [password]
运行cmd:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regsql.exe -ssadd -sstype p -S (local) -U sa -P '1'
此时数据库中创建两张表:ASPStateTempApplications、ASPStateTempSessions。
3>. 设置sessionState
<sessionState mode="SQLServer" sqlConnectionString="data source=127.0.0.1;user id=sa;password=1" cookieless="false" timeout="20"></sessionState>
由于数据不存储在本地内存,存储Session状态的对象需要进行序列化和反序列化,以便通过网络传给数据库服务器,以及从数据库服务器传回。