如下代码,传到另外一个域名就获取不到session了
(localhost:12402/Home/Index)
Session["MemberUser"]=123456;
string url = "api/Home/GetTop8FileDown";
string result = CrossJs.DoGet(ApiUrl + url );
public static string DoGet(string url)
{
CookieContainer cookieContainer = new CookieContainer();
string serviceAddress = url;
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(serviceAddress);
request.Method = "GET";
request.ContentType = "application/json";
HttpWebResponse response =(HttpWebResponse)request.GetResponse();
using (StreamReader dataStream = new StreamReader(response.GetResponseStream()))
{
var result = dataStream.ReadToEnd();
return result;
}
}
(localhost:2412/Home/Index)
public string GetTop8FileDown()
{
int MemberId = Convert.ToInt32(HttpContext.Current.Session["MemberUser"]);
var member = (from a in db.ec_Member where a.MemberID == MemberId select a).FirstOrDefault();
}
一直获取不到这一个HttpContext.Current.Session["MemberUser"] 。
session 因该是应用程序级的 换句话说 共享的媒介是 应用程序
cookie才是浏览器级的 也就是同一个浏览器可以共享cookie 然后基于域名隔离 (但是父子域名可以不受限)
哈哈哈,好奇,刻舟求剑吗。
表示不懂!
@渴死的鱼丶:
好吧,针对你的需求,建议你不要通过Session来传递值。
可以通过Cookie,Url或者Form。
@写代码的小2B: 需要一个安全的传递方式,为什么Session不可以
@渴死的鱼丶:
Session没有跨域的概念,也不是这样用的。
如果需要安全的方式加密后使用Form传递。
@写代码的小2B: Session不是可以资源共享么,在配置里面写个sessionState 存数据库的配置不是可以多域名共享吗,我通过ajax传递跨域都可以读取到Session ,就是换了这个方法不行了
@写代码的小2B: 我想你可能没有理解我的意思,我说的存储会话状态的这种方法我已经试过了,通过AJAX跨域调用时可以的,现在我用的是request.GetResponse()响应,就获取不到Session了。
如果你的session是存在进程中,那么session是无法这样跨程序调用的。
你这个端口不一样(等价于两个域名),所以cookie也无法使用。
这种场景,建议你使用token,或者把session存储在数据库中。
存数据库的意见试过了通过Ajax访问是有Session的,通过request.GetResponse()这个访问就没有了!
@渴死的鱼丶: ajax和一般请求没有本质上的差异,所以应该是你用法不对。
在本回复中,我会以最详细的文字从原理上给你解答,并提出一些修改方案和替代方案。
你之所以遇到这个问题,本质上是对asp.net 的Session这个黑盒子不了解。你试图在服务端帮前端去其它服务实例获取数据,这是可行的设计,问题在于通过Session来验证客户端,导致问题解决起来比较棘手。
方案1:
假设你的代码里很多以方都用了Session,如果弃用Session重构量比较大的话,建议你还是保持使用Session,要做修改的地方是:修改方法是DoGet和修改Session的保存方式或Session的提供者。
默认的Session提供者的配置是把Session数据保存到服务实例进程中,所以其它服务实例比如服务B通过一样的Key去B的进程空间找对应的Session是找不到;如果把配置改为Asp.net状态服务器上,也就是多个服务器实例的都共用同一Session数据,貌似可行,但其实还是不行,因为Session还区分域名,跨了域Session还是不共;把配置改为保存到SqlServer,貌似可以作到多服务实例Session共享,我没有试;我以前自己用memcache来保存Session,自己实例了Session提供者,而不用默认自带的Session提供者,达到Session共享的效果。
除了Session共享配置好之后,你上面的DoGet方法是有问题的,这个方法你是用来帮前端的js从其它服务实例获取数据,你应该把前端传过来的Cookie也进行提交,因为Session的本质是Cookie里的Asp.netSessionID这个Key对应Session服务器里的一个字典,Session["key"]的值是字典的一个名为"Key"的键的值。所以在请求之前,cookieContainer这个实例应该把Request所带的Cookie添加上来,同时为了满足Cookie变化的场景,在请求完成之后,把cookieContainer里的Cookie取出,追加到Response里,达到更新前端的cookie的目的。
方案2:
不使用Session了,因为实在太麻烦了,用token吧,开源有一些项目,或者自己代码实现一个简单的token服务也可以,本质上还是跟Session类似,登录时,把用户信息保存到Token服务器,返回Token,Token设置一个过期时间,反过来,在验证用户时,将用户提交的token去token服务器查询获取用户信息。token服务可以用redis来写一个。
额这个Token没用过,不知道是什么,能不能帮忙弄个填补一下,或者写一个简单的例子