ASP.NET在不同的子域中Session 共享

简介:

今天遇到了这个问题,于是研究了一下。要解决这个问题,首先就要明白一些Session的机理。Session在服务器是以散列表形式存在的,我们都知道Session是会话级的,每个用户访问都会生成一个Session。那么服务器是怎么区分不同用户的Session?又是怎么将不同用户的Session与不同的用户绑定的呢?下面我们来研究一下,以下纯属我个人的理解,如有错误请指证。

  Session在服务器端是以散列表的形式存在的,区分每一个Session是通过SessionID来实现的,所以可以说这个SessionID是一个Key是一个全局唯一的值。我们可以通过ASP.NET来打印出SessionID,如下代码:

protected void Page_Load(object sender, EventArgs e)
        {
            Response.Write(Session.SessionID.ToString());
        }
   这样我们就得到了这样的值:0julmoedn0kz3gyfnr1vksv0,有点像是GUID,就算不是算法也都是类似的,主要就是为了保证全局唯一性。这样就达到了区分不同用户的Session的目的。接下来还有第二个问题,那就是SessionID有了,但是它又是怎么和相应的访问者(用户)绑定的呢?比如说用户A访问维护了自己的SessionID,用户B访问也维护了自己的SessionID。我们都知道web是基于http无链接的,他们又是怎么做到的呢?没错,答案就是在客户端存储了自己的SessionID。浏览器存储SessionID有两种方式,一种就是利用Cookies;还有一种就是利用url参数(这种我们不常用,很不友好)。

  话题说到Cookies上来了,怎么的?没想到Session和Cookies还有这样的关系吧?(很多人知道,别BS我)没错,当我们请求一个URL时候,服务器会生成一个全局的SessionID,并且把这个值以Cookies的形式保存在客户端也就是浏览器(这里暂不讨论url方式)。这样当用户再去请求的时候,在http头把这个SessionID的Cookie发到服务器端,服务器就去找这个SessionID,如果找到了。就证明这个用户的状态是存在的。

  知道了这个原理,我们的问题也就有眉头了,即然是用Cookies来保存SessionID,那么我们就可以在Cooikes上做手脚了。我们都知道Cooikes记录方式是以域(例如:http://www.local.com/)为区分的,这也是各种浏览器规定的。如果不这么做,安全性就会有问题。我们要做的就是让指定Cookies的父域方式,不指定具体指域,这样Cookies就可以跨子域了。Cookies可以像这样指定域:

protected void Page_Load(object sender, EventArgs e)
        {
            Response.Cookies["MyCook"].Domain = ".local.com";
        }
   这样,我们所有的二级域全部是认这一个主域的,比如a.local.com;b.local.com;user.local.com等等。有了这个认识,我想大家心里也有数了,该怎么怎么做,但是现在问题是用来生成SessionID的方法是ASP.NET自动实现的,我们又怎么去干涉它呢?这是这样做的,不主动干涉它,但是我可以操作它的Cookies啊。接下来我们就研究ASP.NET存SessionID的Cooike的名字是什么。经过网上很容易就查找到了,名字是:ASP.NET_SessionId,这个就是SessionId的Cookies名字。我们可以在Session_Start中这样写:

protected void Session_Start(object sender, EventArgs e)
        {
            Response.Cookies["ASP.NET_SessionId"].Value = Session.SessionID.ToString();
            Response.Cookies["ASP.NET_SessionId"].Domain = ".local.com";
        }
   代码的意思是每次会话开始的时候,我都把ASP.NET_SessionId这个Cookie重写成我们已有的SessionID,并且把这个Cookie的domain指定为父域,比如:.local.com,这样就可以实现跨子域的Session共享了。怎么样很简单吧?

  我们还有一个外题问题,就是客户端保存的问题解决了,但是服务器端的Session怎么办?一般情况下我们不同的子域做的是指向不同的服务器的,比如user.local.com 专门一台服务器,yellow.local.com专门一台服务器。这时它们别说是进程了,连物理上都不是一个了。Session怎么共享?这时就用到另一个方法了,我们默认的Session是存储在asp.net进程中的,这样没法互相访问,如下面所示:

<sessionState mode="InProc" />
   我们可以修改为State Server方式,这是一个单独的服务可以用来存储ASP.NET Session的,它支持分布式远程主机的,这样我们可以用一台服务器来提供Session服务,如下所示:

<sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:51515" timeout="30" />
   这样,就完全实现了不同子域的Session共享了。

  前面说到Url保存SessionId的方式,由于不常用,给大家演示一下,如下配置就可以了:

  <sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:51515" timeout="30" cookieless="true" />
   cookieless属性指定是否用cookie来保存SessionId,我们运行一下得到下面的样子:

  http://localhost:3940/(S(dqxcs455n4u2vg55ia51fvqg))/default.aspx
   
   但是其实还有一种方式,因为由于服务器的某些原因,session有丢失的可能(之前的文章有过概述)而且把用户信息存储到服务器内存中也会造成不必要的系统消耗,所以个人感觉可以使用cookies加密的方式把不包含密码的用户信息加密存储到cookies中,让其伴随整个浏览器的请求 ,这样不用担心服务端验证数据丢失的风险,cookies也可以设置一个主域,就像上边说的。


本文转自 tongling_zzu 51CTO博客,原文链接:http://blog.51cto.com/tongling/1176515
相关文章
|
2月前
|
存储 开发框架 NoSQL
ASP.NET WEB——项目中Cookie与Session的用法
ASP.NET WEB——项目中Cookie与Session的用法
36 0
|
3月前
|
开发框架 .NET
ASP.NET Core NET7 增加session的方法
ASP.NET Core NET7 增加session的方法
37 0
|
开发框架 JavaScript .NET
Asp.Net Core中Session使用
Asp.Net Core中Session使用
116 0
|
缓存 前端开发 API
.Net WebApi中使用Session使用
.Net WebApi中使用Session使用
253 0
|
存储 开发框架 .NET
ASP.NET中利用Application和Session统计在线人数、历史访问量
先来简单说一下ASP.NET中的Application和Session 下图是我们非常熟悉的Web应用程序的结构:
ASP.NET中利用Application和Session统计在线人数、历史访问量
|
存储 中间件 .NET
ASP.NET Core Web Api之JWT VS Session VS Cookie(二)
ASP.NET Core Web Api之JWT VS Session VS Cookie(二)前言本文我们来探讨下JWT VS Session的问题,这个问题本没有过多的去思考,看到评论讨论太激烈,就花了一点时间去研究和总结,顺便说一句,这就是写博客的好处,一篇博客写出有的可能是经验积累,有的可能是学习分享,但都逃不过看到文章的你有更多或更好的想法,往返交流自身能收获更多,何乐而不为呢?希望本文能解惑或者能得到更多的交流。
2861 0
|
.NET 容器 开发框架
ASP.NET Core 2 学习笔记(十一)Cookies & Session
原文:ASP.NET Core 2 学习笔记(十一)Cookies & Session 基本上HTTP是没有记录状态的协定,但可以通过Cookies将Request来源区分出来,并将部分数据暂存于Cookies及Session,是写网站常用的用户数据暂存方式。
1329 0
|
SQL Web App开发 存储
艾伟_转载:ASP.NET Session详解
当用户在 Web 应用程序中导航 ASP.NET 页时,ASP.NET 会话状态使您能够存储和检索用户的值。HTTP 是一种无状态协议。这意味着 Web 服务器会将针对页面的每个 HTTP 请求作为独立的请求进行处理。
1137 0
|
Web App开发 存储 SQL