发布到https表单并不总是有效

时间:2009-03-16 15:50:33

标签: php post https

在我的网站上,我有一个简单的登录表单。该页面通过HTTP提供,但表单的POST URL为HTTPS。

通常的方法是用户填写用户名/密码,表单被提交(到完全限定的HTTPS URL,在同一站点上),然后POST处理执行303重定向到用户的主页。但有时这种情况不会发生。

循环(这是100%可重复的)是:

  1. 访问登录表单,填写详细信息并提交
  2. 在服务器上调用登录脚本,验证数据,然后,如果一切正常,则将303重定向到用户主页。
  3. 然后我点击退出然后点击登录,此时我将被带回登录表单
  4. 然后我再次填写我的详细信息,点击提交。
  5. 但是,这次登录逻辑没有执行(步骤2中记录登录的调试代码没有被调用),但我仍然被重定向到用户主页。但是因为我没有成功登录,所以我被踢到头版......
  6. 那么为什么POST不总是调用登录表单?我不认为303正在被缓存(根据规范,它不应该是......)

    查看服务器中的HTTPS日志,第一次调用login.phpo,而不是第二次调用....

    修改

    好的,我们已经解决了这个问题。对于那些感兴趣的人:

    该站点在负载均衡器后面的2个Web服务器上运行。用户会话是“粘性的” - 也就是说,一旦用户在一个Web服务器上浏览,LB就会将它们“附加”到该服务器上。这是通过cookie完成的。但是一旦我们切换到HTTPS,LB就无法读取cookie,因为连接在浏览器和Web服务器之间是加密的。所以它在服务器之间交替。我们有代码在Web服务器之间传播登录身份验证,但这种情况发生得不够快。所以发生的事情是:

    1. 用户浏览器到服务器A,获取一个cookie,说“让我保持A”,填写登录凭据并点击提交
    2. LB无法解密HTTPS流量(以及cookie),将50%的时间发送给B
    3. B验证登录并设置用户在会话中进行身份验证,然后再将用户重定向到非https主页
    4. 由于主页是非https,LB会读取cookie并将其发送给A,A对身份验证一无所知,因为它没有从B传播得足够快......
    5. 解决方案是允许LB解密HTTPS流量,从而确保用户确实留在一个Web服务器上,无论HTTP / HTTPS转换如何。

3 个答案:

答案 0 :(得分:1)

如何“注销”您是否尝试清除缓存以查看是否有任何剩余的会话变量将其丢弃?

在Firefox中:工具 - >清除私人数据 - >检查缓存,Cookie和经过身份验证的会话

答案 1 :(得分:1)

  

我不认为303正在被缓存(根据规范它不应该......)

不,浏览器不会缓存303,但某些其他级别可能会缓存序列中的其他页面。此外,假设您使用cookie来存储登录状态,您需要确保设置'path'和'domain'以便设置和删除相同的cookie,而不是为站点的不同部分设置多个阴影副本

需要更多诊断代码。

  

页面通过HTTP提供,但表单的POST URL为HTTPS。

不要那样做。用户无法在不查看源手动(并检查引用的每个脚本)的情况下告诉“操作”URL将是HTTPS,这是不会发生的。

因此,中间人攻击者可以通过简单地使用登录表单更改初始HTTP页面来获取身份验证详细信息。这使得POST接收器上的任何保护都完全没有用。

登录过程的每个阶段,包括任何包含登录表单的页面,都必须使用HTTPS才能从中获得任何好处。

答案 2 :(得分:0)

我认为,似乎它必定是一个缓存问题。我会在页面上设置标题,以便您明确地不缓存任何内容,并查看其工作原理。

第二个猜测是你有一个会话/ cookie问题(诚然,我没有想过这将如何工作)。在您的注销页面中,您是否明确销毁会话(以及客户端上的任何非永久性cookie)?

最后,您使用的是服务器端缓存吗?我不认为PHP操作码缓存会表现出这种行为,但我看到了memcache的陌生事情(如果你使用的是框架,每个框架的缓存方式都有所不同)。