我只有一个页面要强制作为HTTPS页面访问(Apache上的PHP)。如何在不使整个目录需要HTTPS的情况下执行此操作?或者,如果您从HTTP页面向HTTPS页面提交表单,它是通过HTTPS而不是HTTP发送的吗?
以下是我的例子:
http://www.example.com/some-page.php
我希望它只能通过以下方式访问:
https://www.example.com/some-page.php
当然,我可以将此页面的所有链接指向HTTPS版本,但这并不能阻止某些傻瓜故意通过HTTP访问它...
我认为有一件事是在PHP文件的标题中放置重定向以检查它们是否正在访问HTTPS版本:
if($_SERVER["SCRIPT_URI"] == "http://www.example.com/some-page.php"){
header('Location: https://www.example.com/some-page.php');
}
但这不是正确的方法,可以吗?
顺便说一句,请不要注意URL。我知道如果它实际上是一个有购物车等的页面,你会以不同的方式做到这一点。您可以将其视为一个网站,该网站以一个价格销售一件商品,您可以在其中输入您的信用卡信息,然后将其提交到外部网站上的支付网关,以便明确向您的卡收费一次。答案 0 :(得分:166)
我以前做过的方式基本上就像你写的那样,但没有任何硬编码的值:
if($_SERVER["HTTPS"] != "on") { header("Location: https://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]); exit(); }
答案 1 :(得分:45)
您可以在Apache上使用指令和mod_rewrite来执行此操作:
<Location /buyCrap.php>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</Location>
如果需要,您可以使用regular expressions让位置更智能。
答案 2 :(得分:36)
您应该强制客户端始终使用HTTP Strict Transport Security(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();
}
请注意,HSTS在大多数现代浏览器中都受支持,但不是通用的。因此,如果用户最终使用HTTP,则上述逻辑会手动重定向用户,无论支持如何,然后设置HSTS标头,以便在可能的情况下应由浏览器重定向其他客户端请求。
答案 3 :(得分:14)
我刚刚创建了一个.htaccess文件并添加了:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
简单!
答案 4 :(得分:9)
// 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);
}
答案 5 :(得分:7)
在负载均衡器后面运行时,必须做这样的事情。帽子提示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;
}
}
答案 6 :(得分:5)
http://www.besthostratings.com/articles/force-ssl-htaccess.html
有时您可能需要确保用户通过安全连接浏览您的网站。可以使用包含以下行的.htaccess文件来轻松地将用户重定向到安全连接(https://):
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.example.com/$1 [R,L]
请注意,.htaccess应位于网站主文件夹中。
如果您希望为特定文件夹强制使用HTTPS,则可以使用:
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} somefolder
RewriteRule ^(.*)$ https://www.domain.com/somefolder/$1 [R,L]
.htaccess文件应放在您需要强制HTTPS的文件夹中。
答案 7 :(得分:5)
好的..现在这里有很多东西,但没有人真的完成了 “安全”的问题。对我来说,使用不安全的东西是荒谬的。
除非你用它作诱饵。
$ _ SERVER传播可以根据知道如何的人的意愿进行更改。
同样,Sazzad Tushar Khan和thebigjc表示你也可以使用httaccess来做这个,这里有很多答案包含它。
只需添加:
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://example.com/$1 [R,L]
到你的.httaccess所拥有的那一切,那就是。
我们仍然没有这两种工具那么安全。
其余的很简单。如果缺少属性,即......
if(empty($_SERVER["HTTPS"])){ // SOMETHING IS FISHY
}
if(strstr($_SERVER['HTTP_HOST'],"mywebsite.com") === FALSE){// Something is FISHY
}
另请说您已更新了httaccess文件并检查:
if($_SERVER["HTTPS"] !== "on"){// Something is fishy
}
您可以检查更多变量,即..
HOST_URI
(如果有关于它的静态属性要检查)
HTTP_USER_AGENT
(相同会话的不同值)
因此,当答案在一个组合中时,所有我说的不仅仅是为了解决其中一个。
有关更多httaccess重写信息,请参阅docs-&gt; http://httpd.apache.org/docs/2.0/misc/rewriteguide.html
这里的一些堆栈 - &gt; Force SSL/https using .htaccess and mod_rewrite
和
Getting the full URL of the current page (PHP)
说出一对夫妇。
答案 8 :(得分:3)
使用$_SERVER['HTTPS']
来判断它是否为SSL,如果没有,则重定向到正确的位置。
请记住,显示表单的页面不需要通过HTTPS提供,它是最需要它的回发URL。
编辑:是的,正如下面所指出的,最好是用HTTPS完成整个过程。这让人更放心 - 我指出这个帖子是最关键的部分。此外,您需要注意任何cookie都设置为安全,因此它们只能通过SSL发送。 mod_rewrite解决方案也非常漂亮,我已经用它在我自己的网站上保护了很多应用程序。
答案 9 :(得分:3)
使用htaccess
:
#if domain has www. and not https://
RewriteCond %{HTTPS} =off [NC]
RewriteCond %{HTTP_HOST} ^(?i:www+\.+[^.]+\.+[^.]+)$
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [QSA,L,R=307]
#if domain has not www.
RewriteCond %{HTTP_HOST} ^([^.]+\.+[^.]+)$
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [QSA,L,R=307]
答案 10 :(得分:1)
如果您使用Apache或支持.htaccess文件的LiteSpeed,您可以执行以下操作。 如果您还没有.htaccess文件,则应在根目录中创建一个新的.htaccess文件(通常是index.php所在的位置)。现在将这些行添加为.htaccess中的第一个重写规则:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
您的.htaccess中只需要一次“RewriteEngine On”指令即可获得所有重写规则,所以如果您已经拥有它,只需复制第二行和第三行。
我希望这会有所帮助。
答案 11 :(得分:1)
使用这个还不够:
public static void setColumnOrder(int[] indices, JTable table, TableColumnModel columnModel) {
for (int i = 0; i < indices.length; i++) {
columnModel.moveColumn(i, table.convertColumnIndexToView(indices[i]));
}
}
如果您有任何http内容(如外部http图像源),浏览器将检测到可能的威胁。因此,请确保代码中的所有ref和src都是https
答案 12 :(得分:1)
对于那些使用IIS的人来说,在web.config中添加这一行会有所帮助:
<httpProtocol>
<customHeaders>
<add name="Strict-Transport-Security" value="max-age=31536000"/>
</customHeaders>
</httpProtocol>
<rewrite>
<rules>
<rule name="HTTP to HTTPS redirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" redirectType="Found" url="https://{HTTP_HOST}/{R:1}" />
</rule>
</rules>
</rewrite>
完整的示例文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Strict-Transport-Security" value="max-age=31536000"/>
</customHeaders>
</httpProtocol>
<rewrite>
<rules>
<rule name="HTTP to HTTPS redirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" redirectType="Found" url="https://{HTTP_HOST}/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
答案 13 :(得分:1)
不要在同一页面上混用HTTP和HTTPS。如果你有一个通过HTTP提供的表单页面,我会对提交数据感到紧张 - 我无法查看提交是通过HTTPS还是HTTP进行查看,而不是查看源代码并寻找它。
通过HTTPS提交表单以及提交链接对于优势来说并没有那么大的改变。
答案 14 :(得分:1)
PHP方式:
library(ggplot2)
library(Cairo) # For nicer ggplot2 output when deployed on Linux
library(shiny)
library(readxl)
data(iris)
write.xlsx(x = iris, file = "iris.xlsx")
ui <- fluidPage(
fluidRow(
fileInput(inputId = "file",
label = "Load file"),
column(width = 6,
plotOutput("plot1", height = 350,
click = "plot1_click",
brush = brushOpts(
id = "plot1_brush"
)
),
actionButton("exclude_toggle", "Toggle points"),
actionButton("exclude_reset", "Reset")
)
)
)
server <- function(input, output) {
# Get file
getFile <- reactive({ if (is.null(input$file)) {
return(NULL)
} else {
return(input$file)
}})
# Read data
data <- reactive({ if (is.null(getFile())) {
return(NULL)
} else {
as.data.frame(read_excel(getFile()$datapath))
}})
# For storing which rows have been excluded
vals <- reactiveValues()
observeEvent(data(), {
vals$keeprows <- rep(T, nrow(data()))
})
# Toggle points that are clicked
observeEvent(input$plot1_click, {
res <- nearPoints(data(), input$plot1_click, allRows = TRUE)
vals$keeprows <- xor(vals$keeprows, res$selected_)
})
# Toggle points that are brushed, when button is clicked
observeEvent(input$exclude_toggle, {
res <- brushedPoints(data(), input$plot1_brush, allRows = TRUE)
vals$keeprows <- xor(vals$keeprows, res$selected_)
})
# Reset all points
observeEvent(input$exclude_reset, {
vals$keeprows <- rep(TRUE, nrow(data()))
})
output$plot1 <- renderPlot({
if (is.null(data())) {
return(NULL)
} else {
# Indices for keep and exclude
keep_v <- which(vals$keeprows)
exclude_v <- which(!vals$keeprows)
# Subset data
keep <- data()[keep_v, , drop = F]
exclude <- data()[exclude_v, , drop = F]
ggplot(keep, aes(Sepal.Length, Sepal.Width)) + geom_point() +
geom_smooth(method = lm, fullrange = TRUE, color = "black") +
geom_point(data = exclude, shape = 21, fill = NA, color = "black", alpha = 0.25)
}
})
}
shinyApp(ui, server)
Apache mod_rewrite方式:
$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);
}
答案 15 :(得分:1)
如果您想使用PHP来做到这一点,那么这种方式对我来说真的很好:
<?php
if(!isset($_SERVER["HTTPS"]) || $_SERVER["HTTPS"] != "on") {
header("Location: https://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"], true, 301);
//Prevent the rest of the script from executing.
exit;
}
?>
它检查$ _SERVER超全局数组中的HTTPS变量是否等于“ on”。如果该变量不等于on。
答案 16 :(得分:0)
出于安全原因,您不应该这样做。特别是如果饼干在这里发挥作用。它让你对基于cookie的重放攻击敞开大门。
无论哪种方式,您都应该使用Apache控制规则来调整它。
然后,您可以测试启用的HTTPS,并根据需要重定向。
您应该只使用FORM POST(没有获取)重定向到付费页面, 并且在没有POST的情况下访问页面应该返回到其他页面。 (这会让人们热闹起来。)
http://joseph.randomnetworks.com/archives/2004/07/22/redirect-to-ssl-using-apaches-htaccess/
是一个好的开始,不要提供更多的道歉。但你真的应该通过SSL推送所有内容。
这是过度保护,但至少你有更少的担忧。
答案 17 :(得分:0)
我已经通过许多解决方案来检查 $ _ SERVER [HTTPS] 的状态,但似乎它不可靠,因为有时候它没有设置或设置为on,off等等导致脚本到内部循环重定向。
如果您的服务器支持 $ _ SERVER [SCRIPT_URI]
,这是最可靠的解决方案if (stripos(substr($_SERVER[SCRIPT_URI], 0, 5), "https") === false) {
header("location:https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]");
echo "<meta http-equiv='refresh' content='0; url=https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]'>";
exit;
}
请注意,根据您的安装,您的服务器可能不支持$ _SERVER [SCRIPT_URI],但如果支持,则这是更好的脚本。
您可以在此处查看:Why do some PHP installations have $_SERVER['SCRIPT_URI'] and others not
答案 18 :(得分:0)
也许这个可以帮助,你,这就是我为我的网站所做的,它就像一个魅力:
dataset
答案 19 :(得分:0)
作为替代方案,您可以使用 X-Forwarded-Proto
标头强制重定向到 HTTPS。
在 .htaccess 文件中添加这些行
### Force HTTPS
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
答案 20 :(得分:0)
if(location.protocol!=='https:'){location.replace(`https:${location.href.substring(location.protocol.length)}`);}
答案 21 :(得分:-1)
我使用过这个脚本,它在网站上运行良好。
public void blockingWaitForMessage(long sendTime, String phone) throws InterruptedException{
final CountDownLatch latch = new CountDownLatch(1);
while (!latch.await(5, TimeUnit.SECONDS)) {
if (MessageHandler.getResponse(sendTime, phone)) {
latch.countDown();
}
}
}
答案 22 :(得分:-3)
<?php
// Require https
if ($_SERVER['HTTPS'] != "on") {
$url = "https://". $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
header("Location: $url");
exit;
}
?>
那很容易。