【问题标题】:Session is specific to what? Why not treat ip and domain name session as same?会话具体是什么?为什么不将ip和域名会话视为相同?
【发布时间】:2017-04-11 16:58:56
【问题描述】:

我想知道会话具体是什么?这不仅限于一种语言。 Bellow只是以php为例。

我使用 php session,当我使用我的网站域名时效果很好。为了在 windows 操作系统上的本地 vmvare ubuntu 中测试网站,我更改了 windows 的主机以将 DNS 设置为我的本地 ip。在本地测试时,我使用域名,它也很好用。但是当我将浏览器中的 url 更改为 Ip 时,会话就丢失了。

您可能会混淆我为什么要这样做,因为我还想在我的 android 设备上测试页面,因为没有 android root 我无法更改我的 android 设备的 hosts 文件,所以我必须使用 ip。

你可能也会困惑为什么我不一直使用ip?因为我在我的网络应用程序中使用了第三个开放登录。第三个打开的​​登录桅杆使用域名作为redirectback url,所以当我登录时,它会重定向到域名格式的url。

为什么域名和ip的时候php session是一样的?

要确保php会话与域名和ip不同?我也试过我的管理员系统,上面是用户系统。

我也试试我的管理系统,可以用ip一路登录。但是当我把 ip 改成 url 中的域名时,session 也输了。

【问题讨论】:

  • 特定于域名和服务器。

标签: session url dns ip domain-name


【解决方案1】:

既然您提到了 PHP,我将包含 PHP 手册中的信息。 我相信其他语言的行为类似。

在服务器中,会话特定于 cookie。 来自PHP manual

会话 ID 通常通过会话 cookie 发送到浏览器,该 ID 用于检索现有会话数据。 ID 或会话 cookie 的缺失让 PHP 知道要创建一个新会话,并生成一个新的会话 ID。

在用户代理(客户端,通常是浏览器)中,cookie 特定于域和路径。 来自RFC6265,第 4.1.2.3 节:

Domain 属性指定将 cookie 发送到的那些主机。例如,如果 Domain 属性的值为“example.com”,则用户代理在向 example.com、www.example.comwww.corp.example.com 发出 HTTP 请求时,会将 cookie 包含在 Cookie 标头中。

第 4.1.2.4 节:

仅当 request-uri 的路径部分与 cookie 的 Path 属性匹配(或者是其子目录)时,用户代理才会在 HTTP 请求中包含 cookie,其中 %x2F(“/”)字符被解释为目录分隔符。

所以,如果你从域名到 IP 地址来回移动,例如,example.com12.34.56.78, 服务器为example.com 创建的会话cookie 不会被用户代理发回 如果您稍后向12.34.56.78 发出请求,即使两者是同一台服务器。 对于后面的请求,因为服务器看不到会话 cookie,所以会创建一个新会话并发送一个新 cookie。 这就是为什么同时使用域名和 IP 地址将使用单独的会话。

如果在使用域名和 IP 地址时需要使用相同的会话,则必须在请求之间保留会话 ID。 一种常见的方法是在查询字符串中传递会话 ID。 PHP会话管理,其实也可以配置成使用这个方法,但是我从来不用,所以不能告诉你怎么用。

继续我的示例,您可以将其用于后续请求:

http://12.34.56.78/?sessionId=abcdef0123456789

abcdef0123456789 是一个示例会话 ID。

在 PHP 代码中,在调用 session_start() 之前设置会话 ID。 示例代码:

if(isset($_GET['sessionId']))
    session_id($_GET['sessionId']);
@session_start();

当然,您不必使用sessionId。 您可以使用foobar 或其他任何东西。 您还可以每天甚至每小时更改一次,以防止会话劫持。

更新:要使用foobar,请将PHP代码修改为:

if(isset($_GET['foobar']))
    session_id($_GET['foobar']);
@session_start();

使用该代码,您可以像这样传递会话 ID:

http://12.34.56.78/?foobar=abcdef0123456789

如果你想使用xyz,PHP 代码应该是:

if(isset($_GET['xyz']))
    session_id($_GET['xyz']);
@session_start();

您可以像这样传递会话 ID:

http://12.34.56.78/?xyz=abcdef0123456789

关键是,这完全取决于你。

【讨论】:

  • 你提到了 foobar,你能提供一些关于它的信息吗?
【解决方案2】:

这种行为的原因如下:

创建会话时,其会话 ID 存储在 cookie 中。 cookie 的值由服务器在 HTTP 字段Set-Cookie 中发送。

在客户端向服务器发出下一个请求时,此会话 ID 在 HTTP 字段 Cookie 中被发送回服务器。但是用户代理(浏览器)应该只在特定条件下发送 cookie。基本上,cookie 存储的域必须与服务器的域匹配。但实际上,规则要复杂得多,在RFC 6265 中定义如下:

用户代理必须使用与以下等效的算法
从 cookie 存储和 a
计算“cookie-string”的算法 请求-uri:

  1. 让 cookie-list 是来自 cookie 存储的一组 cookie 满足以下所有要求:

    • 要么:

      cookie 的 host-only-flag 为 true 且规范化 request-host 与 cookie 的域相同。

      或者:

      cookie 的 host-only-flag 为 false 且已规范化 request-host domain-匹配cookie的域。

    • request-uri 的路径 path-match cookie 的路径。

    • 如果 cookie 的 secure-only-flag 为真,那么请求- uri 的方案必须表示一个“安全”协议(定义为 用户代理)。

      注意:“安全”协议的概念不是由 这个文件。通常,用户代理会考虑一个协议 如果协议使用传输层,则安全

安全性,例如 SSL 或 TLS。例如,大多数用户 代理认为“https”是一种表示 安全协议。

  • 如果 cookie 的 http-only-flag 为真,则排除 如果 cookie 字符串是为“非 HTTP" API(由用户代理定义)。

如果您没有勇气阅读所有RFC6265 和相关的RFC,您可以在浏览器中进行一些实验,查看不同情况下的HTTP 标头和存储的cookie。在 Firefox 中,您可以通过以下方式观察到这一点:

  • 按 CTRL+SHIFT+K
  • 点击网络标签
  • 重新加载页面
  • 点击请求

【讨论】:

    猜你喜欢
    • 2014-03-30
    • 2011-11-30
    • 1970-01-01
    • 2023-04-07
    • 2014-06-23
    • 2018-08-27
    • 2017-01-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多