一次域名切换引发的“惨案”

303 阅读6分钟

近期由于公司域名切换,出现很多项目登录不上去的情况。之前遇到过一两次这样的情况,在Chrome浏览器上手动清除Cookies后,再次登录就成功了,但是这次却频繁出现这种情况。

公司官网:www.example.com
数据分析平台:analysis.example.com

操作路径(在同一浏览器上):

  1. 进入数据分析平台登录界面,用户登录,用户退出
  2. 新开窗口,进入官网(不需登录)
  3. 数据分析平台,用户无法登录

经过反复的测试,得出了如上的操作路径。在浏览器控制台发现此操作路径后,数据分析平台网址下的Cookies中有两个PHPSESSIDDomain分别是analysis.example.com.example.com,清除后者即可登录。其他项目也是一样,在进入官网后,其他项目网址对应的Cookies都会有.example.com对应的PHPSESSID信息。

后续通过ini_set()修改官网项目中session对应的变量名,其他项目正常登录。

在解决问题后,温习下CookieSession的小知识。

Cookie

全称HTTP Cookie,也叫 Web Cookie浏览器 Cookie,是一种由服务器端创建,存储在远程浏览器端,并以此来跟踪和识别用户的机制。

主要作用
  • 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
  • 个性化设置(如用户自定义设置、主题等)
  • 浏览器行为跟踪(如跟踪分析用户行为等)

由于涉及到字段和概念较多,本着实用主意,按照基础的函数来讲:
function setcookie (string $name, string $value = "", int $expire = 0, string $path = "", string $domain = "", bool $secure = false, bool $httponly = false) {}

创建Cookie

当服务器收到 HTTP 请求时,服务器可以在响应头里面添加一个 Set-Cookie 选项,体现在Response HeadersSet-Cookie字段。浏览器收到响应后通常会保存下 Cookie,之后对该服务器每一次请求中都通过 Cookie 请求头部将 Cookie 信息发送给服务器,体现在Request HeadersCookie字段。另外,Cookie的过期时间、域、路径、有效期、适用站点都可以根据需要来指定。

// 简单创建例如:
setcookie('cookie_name', 'cookie_value')

// 通过带 array 标记的 Cookie 名称,也可以把 Cookie 设置成数组
setcookie("cookie[three]", "cookiethree");
setcookie("cookie[two]", "cookietwo");
setcookie("cookie[one]", "cookieone");

$nameCookie名称
$valueCookie存储的值

Set-Cookie: <cookie名>=<cookie值>
定义Cookie的生命周期

生命周期定义的两种方式:

  1. 会话期 Cookie,浏览器关闭之后它会被自动删除,也就是说它仅在会话期内有效。会话期Cookie不需要指定过期时间(Expires)或者有效期(Max-Age)。
  2. 持久性 Cookie,取决于过期时间(Expires)或有效期(Max-Age)指定的一段时间。

$expiresCookie 的过期时间,time()+60*60*24*30 就是设置 Cookie 30 天后过期,如果设置成零,或者忽略参数, Cookie 会在会话结束时过期(也就是关掉浏览器时)。

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;

提示:当Cookie的过期时间被设定时,设定的日期和时间只与客户端相关,而不是服务端。

限制访问Cookie

确保 Cookie 被安全发送,并且不会被意外的参与者或脚本访问

$secure:设置这个 Cookie 是否仅仅通过安全的 HTTPS 连接传给客户端。 设置成 true 时,只有安全连接存在时才会设置 Cookie,从 Chrome 52Firefox 52 开始,不安全的站点(http:)无法使用CookieSecure 标记
$httponly:设置成 trueCookie 仅可通过 HTTP 协议访问。 这意思就是 Cookie 无法通过类似 JavaScript 这样的脚本语言访问。 要有效减少 XSS 攻击时的身份窃取行为,可建议用此设置(不是所有浏览器都支持)

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
Cookie的作用域

DomainPath 标识定义了Cookie的作用域:即允许 Cookie 应该发送给哪些URL

$domainCookie 的有效域名/子域名。 设置成子域名(例如 www.example.com),会使 Cookie 对这个子域名和它的三级域名有效(例如 w2.www.example.com)。 要让 Cookie 对整个域名有效(包括它的全部子域名),只要设置成域名就可以了(这个例子里是 example.com
$pathCookie 有效的服务器路径,设置成 '/' 时,Cookie 对整个域名 domain 有效。 如果设置成 '/foo/', Cookie 仅仅对 domain 中 /foo/ 目录及其子目录有效(比如 /foo/bar/)。 默认值是设置 Cookie 时的当前目录。

例如:
如果设置 Domain=mozilla.org,则 Cookie 也包含在子域名中(如developer.mozilla.org)。

Session

Session对象在服务器端,存储特定用户会话所需的属性及配置信息,用于"会话控制";

工作原理
  • 会话由一个唯一标识符标识,可使用session_id函数读取此标识符。为PHP应用程序启用会话状态时,将检查应用程序中每个页面请求是否有浏览器发送的sessionID值。如果未提供任何sessionID值,则PHP将启动一个新会话,并将该会话的sessionID值随响应一起发送到浏览器
  • 默认情况下,sessionID值存储在cookie中,也可以实现在URL中存储sessionID只要一直使用相同的sessionID值来发送请求,会话就被视为活动的,如果特定会话的请求间隔超过指定的超时值(以秒为单位),则该会话被视为已过期。如果使用过期的sessionID值发送的请求将生成一个新的会话
常用配置

基础配置
session.save_handler = files:定义了来存储和获取与会话关联的数据的处理器的名字,默认为文件处理器
session.save_path:定义了传递给存储处理器的参数。如果选择了默认的 files 文件处理器,则此值是创建文件的路径。默认为 /tmp
session.name = PHPSESSID:指定会话名以用做 cookie 的名字。只能由字母数字组成,默认为 PHPSESSID
session.auto_start = 0:指定会话模块是否在请求开始时自动启动一个会话
session.serialize_handler = php:定义用来序列化/解序列化的处理器名字,默认为 PHP 序列化格式
session.use_strict_mode = 0:会话。使用严格模式指定模块是否将使用严格会话id模式。如果启用此模式,则模块不接受未初始化的会话ID。如果从浏览器发送未初始化的会话ID,则会向浏览器发送新的会话ID。应用程序通过严格模式的会话采用来防止会话固定。默认为0(禁用)。

关于Cookie
session.use_cookies = 1:指定是否在客户端用 cookie 来存放会话 ID
session.use_only_cookies = 1:指定是否在客户端仅仅使用 cookie 来存放会话 ID。。启用此设定可以防止有关通过 URL 传递会话 ID 的攻击
session.cookie_lifetime = 0:以秒数指定了发送到浏览器的 cookie 的生命周期。值为 0 表示“直到关闭浏览器”。默认为 0
session.cookie_path = /:指定了要设定会话 cookie 的路径。默认为 /
session.cookie_domain =:指定了要设定会话 cookie 的域名。默认为无,表示根据 cookie 规范产生 cookie 的主机名
session.cookie_httponly =:将cookie标记为只能通过HTTP协议访问。这意味着cookie不能被脚本语言(如JavaScript)访问。
关于gc
session.gc_probability = 1:与 session.gc_divisor 合起来用来管理 gc(garbage collection 垃圾回收)进程启动的概率。默认为 1 session.gc_divisor = 1000:定义了在每个会话初始化时启动 gcgarbage collection 垃圾回收)进程的概率。此概率用 gc_probability/gc_divisor 计算得来。例如 1/100 意味着在每个请求中有 1% 的概率启动 gc 进程。session.gc_divisor 默认为 100。 session.gc_maxlifetime = 1440:指定过了多少秒之后数据就会被视为“垃圾”并被清除 session.cache_expire = 180:以分钟数指定缓冲的会话页面的存活期,此设定对 nocache 缓冲控制方法无效
session.cache_limiter = nocache:指定会话页面所使用的缓冲控制方法
其他
session.referer_check =:包含有用来检查每个 HTTP Referer 的子串。如果客户端发送了 Referer 信息但是在其中并未找到该子串,则嵌入的会话 ID 会被标记为无效。默认为空字符串
session.use_trans_sid = 0:指定是否启用透明 SID 支持。默认为 0(禁用)
session.hash_function = 0:允许用户指定生成会话 ID 的散列算法。'0' 表示 MD5(128 位),'1' 表示 SHA-1(160 位)
session.hash_bits_per_character = 5:允许用户定义将二进制散列数据转换为可读的格式时每个字符存放多少个比特

参考地址: www.php.net/manual/zh/f…