禁用 COOKIE 后如何访问 SESSION 问题

cookie和session有着千丝万缕的关系

cookie和session区别

  • 储存位置的不同
    cookie保存在浏览器客户端
    session保存在服务端(可以是php服务器,redis,数据库)

  • 储存的容量不同
    单个cookie保存的数据<=4KB,一个站点最多保存20个Cookie(浏览器不同而不同)。
    session原则上没有限制,但是考虑到服务器的性能,不宜保存过多的信息,并要有适当的删除机制

  • 储存数据格式不同
    cookie 只能保管ASCII字符串,并需要通过编码方式存储为Unicode字符或者二进制数据
    session 中能够存储任何类型的数据,包括且不限于string,integer,list,map等

  • 隐私策略不同
    cookie 对客户端是可见的,别有用心的人可以分析存放在本地的cookie并进行cookie欺骗,所以它是不安全的。
    session 存储在服务器上,对客户端是透明对,不存在敏感信息泄漏的风险。

  • 有效期上不同
    程序可以通过设置cookie的过期时间,达到使cookie长期有效的效果。
    session 依赖于名为JSESSIONID的cookie,而cookie JSESSIONID的过期时间默认为-1,只需关闭窗口该session就会失效,因而session不能达到长期有效的效果。

  • 服务器压力不同
    cookie 保管在客户端,不占用服务器资源。对于并发用户十分多的网站,cookie是很好的选择。
    session 是保管在服务器端的,每个用户都会产生一个session。假如并发访问的用户十分多,会产生十分多的session,耗费大量的内存。

  • 浏览器支持不同

    • 假如客户端浏览器不支持cookie:
      cookie是需要客户端浏览器支持的,假如客户端禁用了cookie,或者不支持cookie,则会话跟踪会失效。关于WAP上的应用,常规的cookie就派不上用场了。
      运用session需要使用URL地址重写的方式。一切用到session程序的URL都要进行URL地址重写,否则session会话跟踪还会失效。

    • 假如客户端支持cookie:
      cookie既能够设为本浏览器窗口以及子窗口内有效,也能够设为一切窗口内有效。
      session只能在本窗口以及子窗口内有效。

  • 跨域支持上的不同
    cookie支持跨域名访问,例如将domain属性设置为“.baidu.com”,则以“.baidu.com”为后缀的一切域名均能够访问该Cookie。跨域名Cookie如今被普遍用在网络中。
    而Session则不会支持跨域名访问。Session仅在他所在的域名内有效。

当浏览器禁用cookie后如何获取到session

我们知道,当在服务器端启用session时候,数据默认是以文件的形式保存服务器上的,其中session_name(默认是PHPSESSID)和session_id是保存在COOKIE中的,并发送到Client端。此时,用户访问其他页面发送HTTP请求时候依然将cookie中保存的session_name和session_id带回服务器端,而服务器这时候同样启用了session,就会将session_id对应的文件中保存的数据反序列化并保存到$_SESSION数组中。整个流程大概是这样子的。

有一天,客户端无意将COOKIE禁用了,这时候再去服务器端访问上面流程的程序会出现这样的情况。服务器同样会保存session数据到文件中(默认),但是设置的cookie头信息却无法在客户端保存,后面再去访问其他页面时候客户端也就没有带上cookie中的数据去发送请求,然后服务器也就无法获取cookie信息,造成的后果就是上次创建的session文件成为了垃圾数据,而每次请求都要重新创建session文件,然后一直循环~~ 无法跟踪用户登录状态,造成不好的用户体验。

  • 通过php.ini设置来解决

    • 在浏览器开启cookie时候使用cookie保存会话信息,当浏览器禁用cookie时候使用url传递会话信息
      #在php.ini文件中修改
      session.use_trans_sid=1  //启用url传递会话信息
      session.use_only_cookies=0  //关闭只是用cookie保存会话信息
      session.use_cookies=1   //默认使用cookie保存会话信息
    • 不管浏览器是否开启cookie,都使用url的方式传递会话信息
      #在php.ini文件中
      session.use_trans_sid=1 //启用url传递会话信息
      session.use_only_cookies=0 //关闭只是用cookie保存会话信息
      session.use_cookies=0 //不使用cookie保存会话信息
      测试
      //set.php
      ini_set('session.use_trans_sid', 1);
      ini_set('session.use_only_cookies', 0);
      ini_set('session.use_cookies', 0);//全部使用url传递会话信息
      session_start();
      $sid = session_id();
      $_SESSION['abc'] = ['value','value2'];
      echo '<a href="get.php">get</a>';
      //get.php
      session_id($_GET[session_name()]);
      session_start();
      var_dump($_GET[session_name()],$_SESSION, $_COOKIE);
      //可以获取到session
  • 手动URL传值
    为每个链接加上参数,参数值为session_id
    示例

    session_start();//启动session
    $sid = session_id();
    $_SESSION['abc'] = ['value','value2'];//设置session
    $_SESSION['abc2'] = new stdClass();//设置session
    echo '<a href="get.php?sid='.$sid.'">get</a>';//将参数通过get的方式传递
    session_id($_GET['sid']);//获取session_id, 必须在调用 session_start() 函数之前调用 session_id() 函数,否则无法使用该session_id
    session_start();//开启session
    var_dump($_GET['sid'], $_SESSION);
  • 过隐藏表单传递
    在表单中隐藏提交session_id

  • 在数据库中保存session_id, 然后手动调用

Note: 基于 URL 的会话管理比基于 cookie 的会话管理有更多安全风险。例如用户有可能通过 email 将一个包含有效的会话 ID 的 URL 发给他的朋友,或者用户有可能在收藏夹中存有一个包含会话 ID 的 URL 来以同样的会话 ID 去访问站点。

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 1

大佬通过通过 php.ini 设置来解决那一块的测试代码有问题。我那样是获取不到的,但是我换了另一种方式就可以了

2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!