天遇到了这个问题,于是研究了一下。要解决这个问题,首先就要明白一些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:42424" timeout="30" />

这样,就完全实现了不同子域的Session共享了。

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

    <sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" timeout="30" cookieless="true" />

cookieless属性指定是否用cookie来保存SessionId,我们运行一下得到下面的样子:

http://localhost:3380/(S(dqxcs455n4u2vg55ia51fvqg))/default.aspx

ASP.NET中在不同的子域中共享Session的更多相关文章

  1. 转:Spring-session & redis 子域名共享session

    Spring-session & redis 子域名共享session 例子: a.example.com b.example.com spring 版本 4.2.6.RELEASE Spri ...

  2. ASP.NET Web API WebHost宿主环境中管道、路由

    ASP.NET Web API WebHost宿主环境中管道.路由 前言 上篇中说到ASP.NET Web API框架在SelfHost环境中管道.路由的一个形态,本篇就来说明一下在WebHost环境 ...

  3. ASP.NET Web API Selfhost宿主环境中管道、路由

    ASP.NET Web API Selfhost宿主环境中管道.路由 前言 前面的几个篇幅对Web API中的路由和管道进行了简单的介绍并没有详细的去说明一些什么,然而ASP.NET Web API这 ...

  4. ASP.NET MVC搭建项目后台UI框架—8、将View中选择的数据行中的部分数据传入到Controller中

    目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...

  5. 041. asp.net中内容页访问母版页中的控件

    母版页运行机制: 用户通过输入内容也的URL来请求某个页面, 获取该页面后, 读取@Page指令, 如果该指令引用了一个母版页, 则也读取该母版页, 如果也是第一次请求这两个页面, 则母版页和被请求的 ...

  6. Asp.net mvc web api 在项目中的实际应用

    Asp.net mvc web api 在项目中的实际应用 前言:以下只是记录本人在项目中的应用,而web api在数据传输方面有多种实现方式,具体可根据实际情况而定! 1:数据传输前的加密,以下用到 ...

  7. asp.net中父子页面通过gridview中的按钮事件进行回传值的问题

    这两天写BS程序,遇到父子页面传值的问题,以前没写过web系统,用了几天时间才将问题解决,总结下记录下来: 问题描述: 父页面A中有一个gridview,每行6个列,有5列中均有一个按钮,单击按钮,会 ...

  8. 一步步学习ASP.NET MVC3 (5)——View从Action中获得数据

    请注明转载地址:http://www.cnblogs.com/arhat 在上一章中,我们把Razor的模板技术给大家介绍了一下,当然模板中还有其他的知识点,这个以后我们还会继续讲解.本章我们主要讨论 ...

  9. 在ASP.NET MVC5 及 Visual Studio 2013 中为Identity账户系统配置数据库链接及Code-First数据库迁移

    在ASP.NET MVC5 及 Visual Studio 2013 中为Identity账户系统配置数据库链接及Code-First数据库迁移 最近发布的ASP.NET MVC 5 及Visual ...

随机推荐

  1. 计算两个日期相隔的天数(jodd)

    public static void main(String[] args) throws ParseException { System.out.println(TimeUtil.dayOfYear ...

  2. Unity3D之空间转换学习笔记(一):场景物体变换

    该系列笔记基于Unity3D 5.x的版本学习,部分API使用和4.x不一致. 目前在Unity3D中,除了新的UGUI部分控件外,所有的物体(GameObject)都必带有Transform组件,而 ...

  3. 使用Github遇到的问题及解决办法

    问题一: 当push代码上去仓库时,出现 ! [rejected]        master -> master (fetch first) error: failed to push som ...

  4. 简谈java的split

    最近都在处理视频音频,今天在合成音频视频时为了给合成的新文件换个新名字,我打算获取了之前的视频名称,用split来分割出不带后缀的名字,再自己加上后缀. 众所周知split可以分割由某种字符分段的St ...

  5. 配置文件struts2Struts2配置文件模块化包含(include)与action总结

    本文是一篇关于配置文件struts2的帖子 <include>标签 当Struts配置文件比较多,需要模块化分别或分开成为多个配置文件时,这个功能比较好. 则需要使用<include ...

  6. 跨平台实现wchar_t转成char

    位宽.其实知道了这个以后,要在wchar_t 和 char两种类型之间转换就不难实现了. wchar_t 转换为char 的代码如下: 有如下的wchar_t和char变量 wchar_t w_cn ...

  7. GLSL实现Fresnel And Chromatic aberration 【转】

    http://blog.csdn.net/a3070173/archive/2008/11/13/3290091.aspx 使用Shader实现菲涅尔和颜色色散效果很简单,在Cg教程和OpenGL S ...

  8. DOS命令生成文件列表

    DOS命令窗口,生成文件列表命令格式:dir xmlFiles /b >list.txt dir 文件列表相关命令 xmlFiles 待生成文件所在文件夹,在dos命令窗口根目录下,省略前缀.别 ...

  9. easyui textarea IE8中无法换行

    经查 原代码textarea 应用了"textbox"css样式. 默认 white-space:nowrap; 修改为 "nornal",问题解决.

  10. mysql 日期函数格式

    mysql中的from_unixtime函数的format表达式字段描述: %M 月名字(January……December) %W 星期名字(Sunday……Saturday)  %D 有英语前缀的 ...