【问题标题】:PHP Session ID changing on every requestPHP Session ID 随每个请求而改变
【发布时间】:2012-11-09 10:53:20
【问题描述】:

我刚刚将我的应用程序从本地 WAMP 迁移到实际的在线服务器。这导致会话 ID 未按其显示的样子保存。

  • 我检查了 session_start 之前输出的不需要的字符
  • 我的 /tmp 中似乎找不到任何会话文件

这些是我的会话设置:

session.auto_start  Off Off
session.bug_compat_42   Off Off
session.bug_compat_warn On  On
session.cache_expire    180 180
session.cache_limiter   nocache nocache
session.cookie_domain   no value    no value
session.cookie_httponly Off Off
session.cookie_lifetime 0   0
session.cookie_path /   /
session.cookie_secure   Off Off
session.entropy_file    no value    no value
session.entropy_length  0   0
session.gc_divisor  1000    1000
session.gc_maxlifetime  1440    1440
session.gc_probability  1   1
session.hash_bits_per_character 5   5
session.hash_function   0   0
session.name    PHPSESSID   PHPSESSID
session.referer_check   no value    no value
session.save_handler    files   files
session.save_path   /tmp    /tmp
session.serialize_handler   php php
session.use_cookies On  On
session.use_only_cookies    On  On
session.use_trans_sid   0   0
  • 在线服务器正在运行:PHP 版本 5.3.9,而 WAMP 正在运行:PHP 版本 5.3.5。
  • 通过查看发送的标头和每次加载页面时的响应,我得到以下信息,set-cookie 发送适当的会话 ID,收到的响应发送一个新的响应,就好像没有任何请求一样。
  • 我在预览 URL 上运行该站点(启用 SSL)。不知道有没有关系,我的域名还没注册。
  • 错误代码很简单:

    $sId = session_id();

    if ($sId == '') { session_start(); }

【问题讨论】:

  • 感谢您的所有回复。我从 session_start(); 开始现在,我直到执行后期才检查 session_id() (只是为了找出它是哪一个)。我的会话 ID 仍然在每次请求时都在刷新,而无需我调用重新生成的 ID 或类似的东西。只需 session_start -> 存储一些变量 -> 执行结束(应该 write_close) -> 下一页请求 -> Id 和 session 变量不存在。
  • 看来是主持人的预览页面问题。谢谢大家的回答!

标签: php session


【解决方案1】:

我刚刚遇到并解决了完全相同的问题。

事实证明,cookie PHPSESSID(用于记录会话)已发送但被服务器忽略,因此会话未维护,并且每次页面重新加载或更改时服务器都会重新启动会话。

问题是我的 wp-config.php 中有这一行:

@ini_set('session.cookie_secure','On');

这意味着如果连接不安全,每个 cookie 都将被忽略,因此服务器的 PHPSESSID cookie 和会话被重新启动。

检查您的 wp-config.phpinit.php。是 cookie 的问题。

【讨论】:

    【解决方案2】:

    仅使用字母数字字符作为会话 ID。我在使用“。”时遇到了这个问题。作为会话 ID 的一部分。

    【讨论】:

      【解决方案3】:

      您应该首先启动会话才能使用 session_* 函数。所以你需要做的第一件事是:

      session_start();
      

      然后你可以像这样询问会话ID

      $id = session_id();
      

      请注意,不建议将会话保存在可供公众使用的公用文件夹中,因为访问者可以找到您保存会话的文件夹并列出所有会话。然后他们可以将会话 cookie 注入他们的浏览器并控制其他访问者的用户帐户。如果您确实需要这样做,请限制对您的 /tmp 文件夹的访问。例如,使用此代码将 .htaccess 文件放在该文件夹中

      Deny from all
      

      或者找到任何其他方法来禁止用户浏览您的 /tmp 文件夹,因为这可能是安全问题。

      如果您想在每个请求上更改会话 ID,出于安全原因,您可以使用session_regenerate_id function

      你会这样做:

      session_start();
      session_regenerate_id();
      // Do other things you want with sessions.
      

      这样,即使有人窃取了您的会话 cookie,会话 ID 也会在每次请求时更改。这可能是你的问题。 PHP 有一种方法可以在每个请求上重新生成新的会话 id,所以这可能是困扰你的事情。

      至于设置 php.ini 指令,您应该检查您的托管服务提供商是否允许您更改您尝试更改的 .ini 指令。是否可以更改 .ini 指令取决于服务器设置。并且会话的行为方式可能因托管而异,具体取决于它们的服务器设置方式。大多数事情都可以使用 php 函数或使用 ini_set 与此指令列表 php.ini directives 进行更改

      【讨论】:

      • 很抱歉,我可能没有明确表示我想在每个请求中保留相同的会话 ID,并且它会在没有我调用 regenerate 的情况下重置。谢谢。
      • 那么我假设每次请求都会重新生成会话 ID。那是什么样的应用程序?你是从头开始写的,还是它的一些 mvc 框架?您应该检查代码并检查会话是否重新生成,或者询问主机提供商是否重新生成会话。
      • 我已经检查了 PHP 中的会话属性,它似乎没有重置它。以防万一,我会向提供者发布一个问题。如果有任何其他想法,请不要犹豫再次与我联系。该脚本是从头开始编写的,我在输出任何内容之前使用输出缓冲区和会话启动。所以这是无法解释的。错误也会出现,所以如果是输出问题,就会出现问题。再次感谢。
      • 那么这可能是服务器的问题。也许他们将其设置为重新生成会话 ID 以确保安全。真不知道。需要查看代码或服务器设置以帮助您更好地使用此设置。
      【解决方案4】:

      问题很老,最初的问题已经确定。然而,之前的答案最终在这种情况下并没有帮助。因此,如果有人遇到与我类似的问题,这里有另一种方法:

      使用 cookie 管理会话,通常称为 PHPSESSID。如果该 cookie 未正确声明,因此无法包含在用户的后续请求中,则每个请求都会启动另一个会话,导致情况至少与您的相似。

      我试图实现一个在某些反向代理后面运行的应用程序将公共 URL 映射到多个应用程序,例如

      http://public.example.com/foo/bar/script.php
      

      被委派给提供的反向代理后面的某个服务器

      http://foo.example.com/bar/script.php
      

      对于在 foo.example.com 的上下文中运行的 PHP,路径前缀为 /bar 而不是 /foo/bar,设置会话 cookie 的参数 PHPSESSID 在传递给客户时可能会导致问题未经调整。至少在我的情况下,这种观察是正确的。

      【讨论】:

      • 感谢您的回答!这与我的情况相似。
      【解决方案5】:

      你必须写 session_start();在访问任何会话变量之前,没有它您将无法访问会话变量。

      尝试将 session_start() 放在文件的第一行。

      【讨论】:

        【解决方案6】:

        session_start 应该是您文件中的第一件事,之后您可以获取会话 id:

        session_start();
        $sId = session_id();
        

        【讨论】:

          【解决方案7】:

          这可能是由某些程序(即dreamweaver,记事本)在<?php标记之前注入的三个字符(BOM(Byte Order Mark))引起的,因此实际上没有初始化会话。

          如果您启用了error_reporting,您将看到headers already sent..

          使用十六进制编辑器检查您的文件,看看您的编辑器是否注入了任何字符。

          【讨论】:

            猜你喜欢
            • 2020-12-06
            • 1970-01-01
            • 2016-01-12
            • 1970-01-01
            • 2019-09-09
            • 2017-08-03
            • 1970-01-01
            • 2018-12-29
            • 1970-01-01
            相关资源
            最近更新 更多