在服务器上检测 HTTPS 与 HTTP 没有任何用处 [英] Detecting HTTPS vs HTTP on server sending back nothing useful

查看:46
本文介绍了在服务器上检测 HTTPS 与 HTTP 没有任何用处的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

非常类似于检测https请求在 php 中":

想要 https://example.com/pog.php 转到 http://example.com/pog.php,反之亦然.

Want to have https://example.com/pog.php go to http://example.com/pog.php or even vice versa.

问题:

  • 无法从 $_SERVER["HTTPS"] 读取任何内容,因为它不在那里
  • 服务器正在通过端口 80 发送两个请求,因此无法在 HTTPS 版本上检查 443
  • apache_request_headers()apache_response_headers() 发回相同的东西
  • 不能告诉负载均衡器任何事情或让它发送额外的东西
  • 页面在两个 URL 调用上输出的服务器反馈数据与会话 ID 完全相同.无赖.
  • Can't read anything from $_SERVER["HTTPS"] since it's not there
  • Server is sending both requests over port 80, so can't check for 443 on the HTTPS version
  • apache_request_headers() and apache_response_headers() are sending back the same thing
  • Can't tell the loadbalancer anything or have it send extra somethings
  • Server feedback data spat out by the page on both URL calls is exactly the same save for the session ID. Bummer.

是否有任何页面上的方法来检测它是通过 SSL 还是非 SSL 调用的?

Are there any on page ways to detect if it's being called via SSL or non-SSL?

编辑:$_SERVER["HTTPS"] 不存在,打开与否,无论您是通过 SSL 还是非查看站点-SSL.出于某种原因,主机选择为所有加密的 HTTPS 请求提供服务,但在端口 80 下.因此,$_SERVER["HTTPS"] 永远不会打开,不在那里,只是没有有用的反馈那个服务器点.因此该参数始终为空.

Edit: $_SERVER["HTTPS"] isn't there, switched on or not, no matter if you're looking at the site via SSL or non-SSL. For some reason the hosting has chosen to serve all the HTTPS requests encrypted, but down port 80. And thusly, the $_SERVER["HTTPS"] is never on, not there, just no helpful feedback on that server point. So that parameter is always be empty.

(是的,这意味着它会在 FF 或 Chrome 中被标记为部分无效的 SSL 证书.但这部分并不重要.)

(And yeah, that means it gets flagged in say FF or Chrome for a partially invalid SSL certificate. But that part doesn't matter.)

此外,从检测 URL 中可以得到的最多的是斜杠点.PHP 无法查看请求前面是否有 httpshttp.

Also, the most that can be gotten from detecting the URL is up to the point of the slashes. The PHP can't see if the request has https or http at the front.

推荐答案

关键字 -- 负载均衡

问题归结为负载均衡器正在处理 SSL 加密/解密,并且它对网络服务器完全透明.

The problem boils down to the fact that the load balancer is handling SSL encryption/decryption and it is completely transparent to the webserver.

Request:  Client -> 443or80 -> loadbalancer -> 80 -> php
Response: PHP -> 80 -> loadbalancer -> 443or80 -> Client

这里真正的问题是您是否可以控制负载均衡器配置?"

如果您这样做了,有几种方法可以处理它.将负载均衡器配置为对 HTTP 和 HTTPS 具有单独的服务定义.然后将 HTTP 流量发送到 Web 服务器的端口 80,将 HTTPS 流量发送到 Web 服务器的端口 81.(端口 81 没有被其他任何东西使用).

If you do, there are a couple ways to handle it. Configure the load balancer to have seperate service definitions for HTTP and HTTPS. Then send HTTP traffic to port 80 of the web servers, and HTTPS traffic to port 81 of the webservers. (port 81 is not used by anything else).

在apache中,配置两个不同的虚拟主机:

In apache, configure two different virtual hosts:

<VirtualHost 1.2.3.4:80>
   ServerName foo.com
   SetEnv USING_HTTPS 0
   ...
</VirtualHost>

<VirtualHost 1.2.3.4:81>
   ServerName foo.com
   SetEnv USING_HTTPS 1
   ...
</VirtualHost>

然后,环境变量 USING_HTTPS 将是 1|0,具体取决于哪个虚拟主机选择了它.这将在 PHP 的 $_SERVER 数组中可用.是不是很酷?

Then, the environment variable USING_HTTPS will be either 1|0, depending on which virtual host picked it up. That will be available in the $_SERVER array in PHP. Isn't that cool?

如果您无权访问负载均衡器配置,那么事情就有点棘手了.没有办法明确知道您使用的是 HTTP 还是 HTTPS,因为 HTTP 和 HTTPS 是协议.它们指定了如何连接以及通过什么格式发送信息,但在任何一种情况下,您都使用 HTTP 1.1 来发出请求.实际请求中没有信息说明是HTTP还是HTTPS.

If you do not have access to the Load Balancer configuration, then things are a bit trickier. There will not be a way to definitively know if you are using HTTP or HTTPS, because HTTP and HTTPS are protocols. They specify how to connect and what format to send information across, but in either case, you are using HTTP 1.1 to make the request. There is no information in the actual request to say if it is HTTP or HTTPS.

但是不要灰心.有几个想法.

But don't lose heart. There are a couple of ideas.

PHP setcookie() 函数的第 6 个参数可以指示客户端仅通过 HTTPS 连接发送 cookie (http://www.php.net/setcookie).也许您可以使用此参数设置 cookie,然后在后续请求中检查它?

The 6th parameter to PHP's setcookie() function can instruct a client to send the cookie ONLY over HTTPS connections (http://www.php.net/setcookie). Perhaps you could set a cookie with this parameter and then check for it on subsequent requests?

另一种可能性是使用 JavaScript 根据协议更新每个页面上的链接(添加 GET 参数).

Another possibility would be to use JavaScript to update the links on each page depending on the protocol (adding a GET parameter).

(以上都不是防弹的)

另一个实用的选择是在不同的域上获取 SSL,例如 secure.foo.com.然后你可以使用上面的 VirtualHost 技巧.

Another pragmatic option would be to get your SSL on a different domain, such as secure.foo.com. Then you could resort to the VirtualHost trick above.

我知道这不是最简单的问题,因为我在白天处理它(负载均衡网络集群在带有 SSL 模块的 Cisco CSS 负载均衡器后面).

I know this isn't the easiest issue because I deal with it during the day (load balanced web cluster behind a Cisco CSS load balancer with SSL module).

最后,您始终可以认为您的网络应用程序应在需要时切换到 SSL 模式,并相信用户不会将其移回(毕竟,在线上的数据是他们的数据(通常)).

Finally, you can always take the perspective that your web app should switch to SSL mode when needed, and trust the users NOT to move it back (after all, it is their data on the line (usually)).

希望对您有所帮助.

这篇关于在服务器上检测 HTTPS 与 HTTP 没有任何用处的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆