【发布时间】:2010-10-13 15:42:39
【问题描述】:
在我的网站上,我有一个简单的登录表单。该页面通过 HTTP 提供,但表单的 POST URL 是 HTTPS。
通常的方法是用户填写他们的用户名/密码,提交表单(到完全限定的 HTTPS URL,在同一站点上),然后 POST 处理执行 303 重定向到用户的主页。但有时这不会发生。
循环(这是 100% 可重复的)是这样的:
- 访问登录表单,填写详细信息并提交
- 在服务器上调用登录脚本,验证数据,然后,如果一切正常,执行 303 重定向到用户主页。
- 然后我单击注销,然后单击登录,此时我将返回登录表单
- 然后我再次填写我的详细信息,点击提交。
- 然而,这一次,登录逻辑没有执行(在第 2 步记录登录的调试代码没有被调用),但我仍然被重定向到用户主页。但是因为我没有登录成功,所以被踢到首页了……
那么为什么 POST 不总是调用登录表单呢?我认为 303 没有被缓存(根据规范,它不应该被缓存)......
查看服务器中的 HTTPS 日志,login.phpo 是第一次被调用,但不是第二次......
编辑:
好的,我们已经解决了这个问题。有兴趣的朋友:
该网站在负载平衡器后面的 2 个网络服务器上运行。用户会话是“粘性的”——也就是说,一旦用户在一个 Web 服务器上浏览,LB 就会将它们“连接”到该服务器。这是通过 cookie 完成的。但是一旦我们切换到 HTTPS,LB 就无法读取 cookie,因为浏览器和 Web 服务器之间的连接是加密的。所以它在服务器之间交替。我们有代码在网络服务器之间传播登录身份验证,但这发生得不够快。所以发生的事情是:
- 用户浏览器访问服务器 A,得到一个 cookie,上面写着“让我留在 A”,填写他们的登录凭据并点击提交
- LB 无法破译 HTTPS 流量(因此无法破译 cookie),50% 的时间将它们发送给 B
- B 验证登录并将用户设置为在会话中进行身份验证,然后将用户重定向到非 https 主页
- 因为主页不是 https,LB 读取 cookie 并将其发送给 A,A 对身份验证一无所知,因为它从 B 传播的速度不够快...
解决方案是让 LB 解密 HTTPS 流量,从而确保用户确实停留在一个 Web 服务器上,而不管 HTTP/HTTPS 转换如何。
【问题讨论】:
-
如果你能发布你的代码肯定会有帮助。