php 如何强制用户通过 HTTPS 而不是 HTTP 访问我的页面?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/85816/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I force users to access my page over HTTPS instead of HTTP?
提问by Adam Rosenfield
I've got just one page that I want to force to be accessed as an HTTPS page (PHP on Apache). How do I do this without making the whole directory require HTTPS? Or, if you submit a form to an HTTPS page from an HTTP page, does it send it by HTTPS instead of HTTP?
我只有一个页面,我想强制将其作为 HTTPS 页面(Apache 上的 PHP)进行访问。如何在不使整个目录需要 HTTPS 的情况下执行此操作?或者,如果您从 HTTP 页面向 HTTPS 页面提交表单,它是否通过 HTTPS 而不是 HTTP 发送它?
Here is my example:
这是我的例子:
http://www.example.com/some-page.php
I want it to only be accessed through:
我希望它只能通过以下方式访问:
https://www.example.com/some-page.php
Sure, I can put all of the links to this page pointed at the HTTPS version, but that doesn't stop some fool from accessing it through HTTP on purpose...
当然,我可以把指向这个页面的所有链接都指向 HTTPS 版本,但这并不能阻止一些傻瓜故意通过 HTTP 访问它......
One thing I thought was putting a redirect in the header of the PHP file to check to be sure that they are accessing the HTTPS version:
我认为的一件事是在 PHP 文件的标题中放置一个重定向来检查以确保他们正在访问 HTTPS 版本:
if($_SERVER["SCRIPT_URI"] == "http://www.example.com/some-page.php"){
header('Location: https://www.example.com/some-page.php');
}
But that can't be the right way, can it?
但这不可能是正确的方式,对吗?
BTW, please pay no attention to the URL. I know that if it were actually a page where there was a shopping cart, etc., you would do it a different way. Think of it as a page from a site that sells one item for one price where you type in your credit card info to be submitted to a payment gateway on an external site for the express purpose of charging your card one time.
顺便说一句,请不要注意 URL。我知道如果它实际上是一个有购物车等的页面,你会用不同的方式来做。可以把它想象成一个网站的页面,该页面以一个价格出售一件商品,您可以在其中输入信用卡信息,提交到外部网站上的支付网关,以明确地向您的卡收取一次费用。
回答by Adam Rosenfield
The way I've done it before is basically like what you wrote, but doesn't have any hardcoded values:
我以前做的方式基本上和你写的一样,但没有任何硬编码值:
if($_SERVER["HTTPS"] != "on")
{
header("Location: https://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]);
exit();
}
回答by thebigjc
You could do it with a directive and mod_rewrite on Apache:
您可以在 Apache 上使用指令和 mod_rewrite 来实现:
<Location /buyCrap.php>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</Location>
You could make the Location smarter over time using regular expressionsif you want.
如果需要,您可以使用正则表达式使位置随着时间的推移变得更智能。
回答by Jacob Swartwood
You should force the clientto request HTTPS always with HTTP Strict Transport Security(HSTS) headers:
您应该强制客户端始终使用HTTP 严格传输安全(HSTS) 标头请求 HTTPS :
// Use HTTP Strict Transport Security to force client to use secure connections only
$use_sts = true;
// iis sets HTTPS to 'off' for non-SSL requests
if ($use_sts && isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') {
header('Strict-Transport-Security: max-age=31536000');
} elseif ($use_sts) {
header('Location: https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'], true, 301);
// we are in cleartext at the moment, prevent further execution and output
die();
}
Please note that HSTS is supported in most modern browsers, but not universal. Thus the logic above manually redirects the user regardless of support if they end up on HTTP, and then sets the HSTS header so that further client requests should be redirected by the browser if possible.
请注意,大多数现代浏览器都支持 HSTS,但并不普遍。因此,如果用户最终使用 HTTP,则上述逻辑会手动重定向用户,而不管用户是否支持,然后设置 HSTS 标头,以便浏览器应尽可能重定向进一步的客户端请求。
回答by MatHatrik
I just created a .htaccess file and added :
我刚刚创建了一个 .htaccess 文件并添加了:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
Simple !
简单的 !
回答by Jeff
// Force HTTPS for security
if($_SERVER["HTTPS"] != "on") {
$pageURL = "Location: https://";
if ($_SERVER["SERVER_PORT"] != "80") {
$pageURL .= $_SERVER["SERVER_NAME"] . ":" . $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"];
} else {
$pageURL .= $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"];
}
header($pageURL);
}
回答by syvex
Had to do something like this when running behind a load balancer. Hat tip https://stackoverflow.com/a/16076965/766172
在负载均衡器后面运行时不得不做这样的事情。帽子提示https://stackoverflow.com/a/16076965/766172
function isSecure() {
return (
(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
|| $_SERVER['SERVER_PORT'] == 443
|| (
(!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
|| (!empty($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] == 'on')
)
);
}
function requireHTTPS() {
if (!isSecure()) {
header('Location: https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], TRUE, 301);
exit;
}
}
回答by Jay
The PHP way:
PHP方式:
$is_https=false;
if (isset($_SERVER['HTTPS'])) $is_https=$_SERVER['HTTPS'];
if ($is_https !== "on")
{
header("Location: https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
exit(1);
}
The Apache mod_rewrite way:
Apache mod_rewrite 方式:
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
回答by JSG
Ok.. Now there is tons of stuff on this now but no one really completes the "Secure" question. For me it is rediculous to use something that is insecure.
好的.. 现在有很多关于这个的东西,但没有人真正完成“安全”问题。对我来说,使用不安全的东西是可笑的。
Unless you use it as bait.
除非你把它当作诱饵。
$_SERVER propagation can be changed at the will of someone who knows how.
$_SERVER 传播可以根据知道如何更改的人的意愿进行更改。
Also as Sazzad Tushar Khan and the thebigjc stated you can also use httaccess to do this and there are a lot of answers here containing it.
Just add:
同样,正如 Sazzad Tushar Khan 和 thebigjc 所说,你也可以使用 httaccess 来做到这一点,这里有很多包含它的答案。
只需添加:
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://example.com/ [R,L]
to the end of what you have in your .httaccess and thats that.
到你的 .httaccess 文件的最后,就是这样。
Still we are not as secure as we possibly can be with these 2 tools.
尽管如此,我们仍然没有像使用这两个工具那样安全。
The rest is simple. If there are missing attributes ie...
剩下的很简单。如果缺少属性,即...
if(empty($_SERVER["HTTPS"])){ // SOMETHING IS FISHY
}
if(strstr($_SERVER['HTTP_HOST'],"mywebsite.com") === FALSE){// Something is FISHY
}
Also say you have updated your httaccess file and you check:
还说您已更新 httaccess 文件并检查:
if($_SERVER["HTTPS"] !== "on"){// Something is fishy
}
There are a lot more variables you can check ie..
您可以检查更多变量,即..
HOST_URI(If there are static atributes about it to check)
HOST_URI(如果有关于它的静态属性要检查)
HTTP_USER_AGENT(Same session different values)
HTTP_USER_AGENT(同一会话不同的值)
So all Im saying is dont just settle for one or the other when the answer lies in a combination.
For more httaccess rewriting info see the docs-> http://httpd.apache.org/docs/2.0/misc/rewriteguide.html
Some Stacks here -> Force SSL/https using .htaccess and mod_rewrite
and
Getting the full URL of the current page (PHP)
to name a couple.
因此,当答案在于组合时,我所说的只是不要只满足于其中之一。
有关更多 httaccess 重写信息,请参阅文档-> http://httpd.apache.org/docs/2.0/misc/rewriteguide.html
此处的某些堆栈->使用 .htaccess 和 mod_rewrite 强制 SSL/https
并
获取完整的 URL当前页面 (PHP)
来命名一对。
回答by itsazzad
http://www.besthostratings.com/articles/force-ssl-htaccess.html
http://www.besthostratings.com/articles/force-ssl-htaccess.html
Sometimes you may need to make sure that the user is browsing your site over securte connection. An easy to way to always redirect the user to secure connection (https://) can be accomplished with a .htaccess file containing the following lines:
有时您可能需要确保用户通过安全连接浏览您的网站。可以使用包含以下几行的 .htaccess 文件来实现始终将用户重定向到安全连接 (https://) 的简单方法:
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.example.com/ [R,L]
Please, note that the .htaccess should be located in the web site main folder.
请注意,.htaccess 应位于网站主文件夹中。
In case you wish to force HTTPS for a particular folder you can use:
如果您希望为特定文件夹强制使用 HTTPS,您可以使用:
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} somefolder
RewriteRule ^(.*)$ https://www.domain.com/somefolder/ [R,L]
The .htaccess file should be placed in the folder where you need to force HTTPS.
.htaccess 文件应放置在您需要强制使用 HTTPS 的文件夹中。
回答by DGM
Use $_SERVER['HTTPS']to tell if it is SSL, and redirect to the right place if not.
用$_SERVER['HTTPS']说,如果它是SSL,并重定向到正确的地方,如果没有。
And remember, the page that displays the form does not need to be fed via HTTPS, it's the post back URL that needs it most.
请记住,显示表单的页面不需要通过 HTTPS 提供,它是最需要它的回发 URL。
Edit: yes, as is pointed out below, it's best to have the entire process in HTTPS. It's much more reassuring - I was pointing out that the post is the most critical part. Also, you need to take care that any cookies are set to be secure, so they will only be sent via SSL. The mod_rewrite solution is also very nifty, I've used it to secure a lot of applications on my own website.
编辑:是的,正如下面所指出的,最好在 HTTPS 中进行整个过程。这更让人放心——我指出帖子是最关键的部分。此外,您需要注意将所有 cookie 设置为安全的,因此它们只能通过 SSL 发送。mod_rewrite 解决方案也非常漂亮,我用它来保护我自己网站上的许多应用程序。

