【问题标题】:Problem Setting Cookie w/ PHP使用 PHP 设置 Cookie 的问题
【发布时间】:2009-09-02 21:29:33
【问题描述】:

我在本地跨两个“域”工作。我的机器上有 enterprise.local 和 application.local 虚拟主机,我需要为“local”或“.local”设置域 cookie,但在正确设置 cookie 时遇到了一些麻烦。在 application.local 中,我有这个:

setcookie( 'iPlanetDirectoryPro', trim( $token_id ), '0', '/', '.local' );
header( 'Location: /adcom-sso' );

我也试过这个:

header( 'Set-Cookie: iPlanetDirectoryPro=' . trim( $token_id ) . '; path=/' );
header( 'Location: /adcom-sso' );

使用setcookie(),不会设置任何cookie。使用Set-Cookie 标头,cookie 集。我已经从两者中删除了重定向,结果永远不会改变。它适用于Set-Cookie,但不适用于setcookie()。这很好,因为我真的不喜欢我使用哪种解决方案,但是在Set-Cookie 解决方案中,只要我添加一个域,它就会全部崩溃:

header( 'Set-Cookie: iPlanetDirectoryPro=' . trim( $token_id ) . '; path=/; domain=local' );

添加域值后,我得到一个标题错误:

Header may not contain more than a single header, new line detected.

我已尝试将域值设为“local”和“.local”。行为没有改变。

我很少需要显式访问 cookie,所以我希望我只是遗漏了一些明显的东西,但我肯定看不到。任何见解将不胜感激。

更新:我想我已经进一步缩小了范围。只要我不包含域值,这两种方式似乎都可以工作。使用“local”或“.local”作为 cookie 的特定域会不会有问题?

【问题讨论】:

    标签: php cookies opensso


    【解决方案1】:

    编辑: 我现在看过RFC2109, 4.3.2 Rejecting Cookies:

    • Domain 属性的值不包含嵌入的点或 不以点开头。

      ...

    • Domain=.com 或 Domain=.com. 的 Set-Cookie 将始终 被拒绝,因为没有嵌入点。

    出于安全考虑,浏览器似乎拒绝“.local”。要为域设置 cookie,它必须至少有两个点(例如 '.cookiedomain.local')。

    AFAIK 无法从一个子域(例如 one.local)为另一个子域(例如 another.local)设置 cookie。您可以做些什么来克服这个问题,将用户重定向到一个 cookie 域,该域设置/获取所有 cookie,并将用户再次重定向到他们来自的位置,并将 url 中包含的 cookie 数据作为查询参数。 Microsoft 为自己的域(msn.com、microsoft.com)这样做(或确实)这样做了。


    只有当您作为参数传递给header() 的字符串包含不跟空格或制表符 (这将继续下一行的标题)。

    现在,setcookie() 实际上是 urlencode() 的值(setrawcookie() 不会),因此换行不会导致错误。

    另一方面,trim() 函数将仅从其参数的开头和结尾去除空格,并保留任何其他换行符不变。所以也许你可以试试preg_replace('/\s+/', '') 之类的东西。

    为什么setcookie() 方法对您不起作用对我来说并不明显。可能是您实际上看到了 cookie(使用 setcookie() 设置),但不希望其中包含 url 转义,而是在代码中的某处默默地拒绝它。

    但是,这并不能解释为什么您的第一个 header() 似乎有效(其中包含换行符);似乎您的某些 cookie 值中有换行符,而有些则没有。

    顺便说一句,如果您希望子域看到 cookie,将域设置为“.local”(前导“.”)是正确的做法。

    PHP 文档(尤其是用户 cmets)中讨论了有关使用 setcookie() 设置 cookie 的一些额外注意事项。

    【讨论】:

    • 我实际上已经尝试了所有这些。最初,我根本没有修剪。我也尝试了 setrawcookie(),但为了简单起见,我没有在此处包含它。在 Set-Cookie 解决方案中,我还尝试手动 urlencode()'ing $token_id。我只是尝试了 preg_replace() 的想法,它并没有改变任何东西。谢谢。
    • “标题可能不包含...”将不会被触发,除非您在其中有换行符。我查看了 PHP 源代码 (sapi_header_op())。你肯定有这个错误的换行问题。
    • 我最终追踪到的内容与您的编辑相符。我一尝试“.local.com”,一切都很顺利。在这种情况下,问题是因为我的开发环境让我的“域”保持简单。在生产环境的堆栈中,它永远不会成为问题。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 2014-06-02
    • 1970-01-01
    • 2011-06-30
    • 1970-01-01
    • 2015-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多