ASP.NET中的SESSION
基本概念
由于HTTP协议是无状态的,所以在ASP.NET模型中为了维护用户的状态信息,设计了状态管理,对了页面来说,每一次请求,Page对象都会重新创建,页面的控件及内容都会重新生成。 SESSION机制是一种服务器端的机制,当某个客户端的请求创建一个会话的时候,服务器首先检查这个客户端的请求里是否已包含了一个session标识session id用来标识是否是一次同一个会话。保存这个session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发挥给服务器。一般这个cookie的名字都是类似于SEEESIONID。
简单的说,Session是ASP.NET实现的一种服务端会话技术,Session就是服务器给客户端的一个编号,当一台web服务器运行时,当每个用户首次与这台服务器建立连接时,它就与这个服务器建立了一个Session,同时服务器就会自动为其分配一个SessionId,用以标识这个用户的唯一身分,这个Session就是有服务器随机产生的一个由24个字符组成的字符串。 当这个ID值都是可以配置的
<sessionState mode="InProc" cookieName="My_SessionID" cookieless="AutoDetect" timeout="30"/>
这个唯一的SessionId还是有很大的实际意义,当一个用户提交表单时,浏览器就会将用户的SessionId自动附加在HTTP头信息中,当服务器处理完这个表单后,就会将结果返回给SessionId所对应的用户。
默认配置
默认 <sessionState> 元素不是在 Machine.config 文件或根 Web.config 文件中显式配置的。而是由应用程序返回的默认配置
<sessionState mode="[Off|InProc|StateServer|SQLServer|Custom]" timeout="number of minutes" cookieName="session identifier cookie name" cookieless= "[true|false|AutoDetect|UseCookies|UseUri|UseDeviceProfile]" regenerateExpiredSessionId="[True|False]" sessionIDManagerType="session manager type" sqlConnectionString="sql connection string" sqlCommandTimeout="number of seconds" allowCustomSqlDatabase="[True|False]" useHostingIdentity="[True|False]" stateConnectionString="tcpip=server:port" stateNetworkTimeout="number of seconds" customProvider="custom provider name" compressionEnabled="[True|False]" sqlConnectionRetryInterval="number of seconds"> <providers>...</providers> </sessionState>
配置当前应用程序的会话状态设置。
<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"/>
指定存储会话状态的位置。 Off 指示会话状态没有启用。 InProc 指示本地存储会话状态。 StateServer 指示在远程服务器上存储会话状态。 SQLServer 指示在 Microsoft SQL Server? 上存储会话状态。 cookieless 指定是否应该使用没有 Cookie 的会话来标识客户端会话。 true 指示应该使用没有 Cookie 的会话。 false 指示不应使用没有 Cookie 的会话。默认值是 false。 timeout 指定会话在被放弃前处于空闲状态的分钟数。默认值是 20。 stateConnectionString 指定远程存储会话状态所在的服务器名称和端口。例如,"tcpip=127.0.0.1:42424"。当 mode 为 StateServer 时,需要使用此属性。 sqlConnectionString 为 SQL Server 指定连接字符串。例如,"data source=localhost;Integrated Security=SSPI;Initial Catalog=northwind"。当 mode 为 SQLServer 时,需要使用此属性。 stateNetworkTimeout 当使用 StateServer 模式存储会话状态时,指定在会话被放弃前 Web 服务器和状态服务器之间的 TCP/IP 网络连接处于空闲状态的秒数。默认值是 10。 使用 StateServer 模式 确保在存储会话状态信息的远程服务器上正在运行 ASP.NET 状态服务。此服务随 ASP.NET 一起安装,并且默认位于 <Drive>:\systemroot\Microsoft.NET\Framework\version\aspnet_state.exe。 在应用程序的 Web.config 文件中,设置 mode=StateServer 并设置 stateConnectionString 属性。例如,stateConnectionString="tcpip=sarath:42424"。 使用 SQLServer 模式 在运行 SQL Server 的计算机(将存储会话状态)上运行 InstallSqlState.sql(默认安装在 <Drive>:\systemroot\Microsoft.NET\Framework\version 中)。它将使用新的存储过程和 TempDB 数据库中的 ASPStateTempApplications 和 ASPStateTempSessions 表创建一个称为 ASPState 的数据库。 在应用程序的 Web.config 文件中,设置 mode=SQLServer 并设置 sqlConnectionString 属性。例如,sqlConnectionString="data source=localhost;Integrated Security=SSPI;Initial Catalog=northwind"。一般的小的应用我习惯放在ASP.NET State Service中(需要确保服务开启) ,如果想要共享SESSION的话,也可以配置放在单独的服务器中,或者保证在数据库中。
依赖性
默认SessionId会以HttpOnly会话的形式储存在Cookie中(默认值为UseCookies)
可以设置cookieless的值来决定SessionId的存储位置
成员名称 | 说明 | |
---|---|---|
AutoDetect | ASP.NET 确定请求浏览器或设备是否支持 Cookie。如果请求浏览器或设备支持 Cookie,则 AutoDetect 使用 Cookie 来保持用户数据;否则在查询字符串中使用标识符。如果浏览器或设备支持使用 Cookie,但当前 Cookie 被禁用,请求功能仍将使用 Cookie。 | |
UseCookies | 使用 Cookie 保持用户数据,无论浏览器或设备是否支持 Cookie。 | |
UseDeviceProfile | ASP.NET 根据 System.Web.HttpBrowserCapabilities 设置来确定是否使用 Cookie。如果该设置指示浏览器或设备支持 Cookie,则使用 Cookie;否则在查询字符串中使用标识符。 | |
UseUri | 该调用功能使用查询字符串来存储标识符,无论浏览器或设备是否支持 Cookie。 |
HttpCookieMode 枚举
//指定如何将 Cookie 用于 Web 应用程序。 public enum HttpCookieMode { // 该调用功能使用查询字符串来存储标识符,无论浏览器或设备是否支持 Cookie。 UseUri = 0, // 使用 Cookie 保持用户数据,无论浏览器或设备是否支持 Cookie。 UseCookies = 1, // ASP.NET 确定请求浏览器或设备是否支持 Cookie。如果请求浏览器或设备支持 Cookie,则 System.Web.HttpCookieMode.AutoDetect // 使用 Cookie 来保持用户数据;否则在查询字符串中使用标识符。如果浏览器或设备支持使用 Cookie,但当前 Cookie 被禁用,请求功能仍将使用Cookie。 AutoDetect = 2, // ASP.NET 根据 System.Web.HttpBrowserCapabilities 设置来确定是否使用 Cookie。如果该设置指示浏览器或设备支持 // Cookie,则使用 Cookie;否则在查询字符串中使用标识符。 UseDeviceProfile = 3, }
SESSION默认是依赖于Cookie,如果禁用了Cookie,服务端必须有其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面或者表单隐藏字段来实现
如商城中购物车中的数据若维系在Session中,如果浏览器禁用了Cookie,那么就会无法使用了(只限UseCookies),当然一般不会局限于Cookie,如亚马逊禁止Cookie,一样可以购买商品。如果设置为UseUri,则SessionId会跟随在地址栏中
<sessionState mode="InProc" cookieName="My_SessionID" cookieless="UseUri" timeout="30"/>
SESSION存储
关闭浏览器SEESION就丢失了吗,可以这样解释,服务端跟根据会话设置的时间来确定SESSION的驻留时间,而关闭浏览器具体要看是否设置了cookie的有效期,如果是会话的Cookie那么肯会不能得到上次的会话的。
严格说来不算持久化保存,因为session实际上还是保存在内存里,也可以在服务端得到SEESIONID值取得SESSIION的内容,序列化对象放在其他地方,例如session能够在集群中被复制或者能够持久保存例如MangDB ,Memcached等(正式项目我都没有试过)。
SESSION的缺陷
程依赖性:ASP Session状态存于IIS的进程中当进程崩溃时,这些信息也就丢失。另外,重起或者关闭IIS服务都会造成信息的丢失
Cookie的依赖性:实际上客户端的Session信息是存储与Cookie中的,如果客户端完全禁用掉了Cookie功能,他也就不能享受到了Session提供的功能了
不过这些缺点可以通过改变存储的方式来控制的。
SESSION共享
一个大项目被分割成若干小项目开发,为了能够互不干扰,要求每个小项目作为一个单独的web应用程序开发,可是到了最后突然发现某几个小项目之间需要共享一些信息
SSO,在session中保存的用户信息,最自然的要求是应用程序间能够访问彼此的session。
负载平衡,如Nginx的负载平衡 可以设置 一些配置参数或者基于硬件来确保同一会话是请求的同一台服务器
SESSION与缓存
异同:
session 信息存于服务端,在交互时传到客户端一个sessionid,客户端请求数据时发送sessionid用于识别
cookies 信息存于客户端,在效互时客户端将信息发送至服务端,安全性较差.
cache 用于可以理解缓冲数据,通常为网页及对象,在涉及安全性的动态生成页面上,可以设置有较时间,以便减少攻击
缺点:
session比较可靠,除非应用程序被重起,否则不会消失。使用state server或者SQL Server来保存session数据会更持久。
cache不可靠,会随时被根据系统要求而清除,但是自动管理过期时间和依赖,名副其实地是缓存的作用。
cookie会在客户端浏览器和服务器之间来回丢来丢去,是最原始的保存用户信息的形式,对加密、性能等都无从考虑(当然在这个系统上扩展以后可以达到),并且浏览器对其大小限制得很紧。
具体什么时候用得看实际场景了。
SESSION异常丢失
1.Global.asax或者Web.config文件被更改
2.Bin文件夹中的Web程序(DLL)被修改
3.ASP.NET State Service 服务或者进程挂了
3.杀毒软件扫描了config文件 (这个具体不清楚)
Refer:
http://support.microsoft.com/kb/316148/zh-cn
http://www.cnblogs.com/fish-li/archive/2011/07/31/2123191.html
http://www.cnblogs.com/skynet/archive/2010/04/02/1703380.html
Exploring Session in ASP.NET(好文)
http://www.codeproject.com/Articles/32545/Exploring-Session-in-ASP-Net