【问题标题】:http to https redirection through htaccess: incorrect redirection errorhttp 到 https 通过 htaccess 重定向:不正确的重定向错误
【发布时间】:2017-07-24 15:52:44
【问题描述】:

我需要将所有 HTTP 请求重定向到 HTTPS:

RewriteEngine On
RewriteBase /

RewriteCond %{HTTP_HOST} !^some-domain\.com$ [NC]
RewriteRule ^(.*)$ https://some-domain.com/$1 [R=301,L]

RewriteCond %{THE_REQUEST} /(\.+) [OR]
RewriteCond %{THE_REQUEST} /(\?+) [OR]
RewriteCond %{THE_REQUEST} /(/+)
RewriteRule ^(.*)$ 404.html [L]
RewriteRule ^core/(install|temp|smarty|modules|languages|includes|functions|fonts|files|config|classes|cache|backup|tpl)/(.*) - [F]
RewriteRule ^data/(.+)\.(tpl\.html|php|php3|php4|php5|phtml|pl|cgi) - [F]
RewriteRule ^install_check\.html$ install.php?check=yes [L]
RewriteRule ^index\.html$ index.php [L]
RewriteRule ^news\.html$ index.php?news=yes [L]
RewriteRule ^price\.html$ index.php?show_price=yes [L]
RewriteRule ^cart\.html$ index.php?shopping_cart=yes [L]
RewriteRule ^wide_search\.html$ index.php?search_with_change_category_ability=yes [L]
RewriteRule ^feedback\.html$ index.php?feedback=yes [L]
RewriteRule ^compare\.html$ index.php?comparison_products=yes [L]
RewriteRule ^page_([0-9]+)\.html$ index.php?show_aux_page=$1 [L]
RewriteRule ^product_([0-9]+)\.html$ index.php?productID=$1 [L]
RewriteRule ^category_([0-9]+)\.html$ index.php?categoryID=$1 [L]
RewriteRule ^category_([0-9]+)_offset_([0-9]+)\.html$ index.php?categoryID=$1&offset=$2 [L]
RewriteRule ^category_([0-9]+)_show_all\.html$ index.php?categoryID=$1&show_all=yes [L]
RewriteRule ^show_news_([0-9]+)\.html$ index.php?fullnews=$1 [L]

# BEGIN Articles
RewriteRule ^poleznoe/([^/]+)\.html$ index.php?fullarticles=$1 [L]
RewriteRule ^poleznoe/([0-9]+)/$ index.php?articles=yes&offset=$1 [L]
RewriteRule ^poleznoe/$ index.php?articles=yes [L]
# END Articles

RewriteRule ^google([a-z0-9_-]+).html$ google$1.html [L]
RewriteRule ^yandex([a-z0-9_-]+).html$ yandex$1.html [L]

# BEGIN Human friendly URL's
RewriteRule ^news/([^/]*).html$ index.php?uri=$1&uriFor=news [L]
RewriteRule ^([^/]*).html$ index.php?uri=$1&uriFor=pages [L]
RewriteRule ^([^/]*)/$ index.php?uri=$1&uriFor=category [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !([^/]*)/$
RewriteRule ^([^/]*)$  $1/ [L,R=301]
RewriteRule ^(([^/]*)_offset_([0-9]+))/$ index.php?uri=$1&uriFor=category&offset=$2 [L]
RewriteRule ^([^/]*)_show_all/$ index.php?uri=$1&uriFor=category&show_all=yes [L]
#RewriteRule ^([^/]*)/([^/]*)/([^/]*)\.html$ index.php?uri=$3&uriFor=product [L]
RewriteRule ^([^/]*)/([^/]*)\.html$ index.php?uri=$2&uriFor=product [L]
# END Human friendly URL's

我在 Google 上搜索过几次并遇到过这个解决方案:

RewriteCond %{HTTPS} off
RewriteRule ^.*$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

但如果我把它放在RewriteEngine On 之后或RewriteBase / 之后或附近或之间的任何地方

RewriteCond %{HTTP_HOST} !^some-domain\.com$ [NC]
RewriteRule ^(.*)$ https://some-domain.com/$1 [R=301,L]

当我加载页面时,它给了我一个不正确的重定向错误。请告诉我我做错了什么。

【问题讨论】:

  • 您的 SSL 是如何管理的?您是否在应用程序服务器上直接安装了 SSL 证书? “不正确的重定向错误”是什么意思?浏览器是否报告了重定向循环?
  • 或者.... 检查$_SERVER 数组的转储并检查HTTPSX-Forwarded-Proto 的值(可能还有其他一些特定于服务器的X-.... 标头?)。
  • 因为我们需要找出不起作用的原因以及用于服务器配置的正确指令。您发布的重定向代码没有任何“错误” - 该代码在大多数安装了 SSL 证书的站点/服务器上都可以正常工作(这就是为什么您“多次”找到相同的代码 - 它可以工作)。但由于某种原因,它无法在您的站点/服务器上运行 - 这是“好的” - 该代码无法在 every 服务器配置上运行。但通常有一个很好的理由让它不起作用 - 这就是为什么我要专门询问如何 SSL证书是实施的,而不是“SSL是否有效”。
  • 重定向循环最可能的原因是HTTPS 服务器变量未设置,或未按预期设置。如果是这种情况,那么我们需要找到另一个要使用的服务器变量。我会将SERVER_PORT 添加到要检查的$_SERVER 变量列表中。
  • 哦!从来不知道,对不起。实际上 $_SERVER['HTTPS'] 总是空的,但是当我在 https 页面上时,$_SERVER['HTTP_X_FORWARDED_PROTO'] 返回 https

标签: apache .htaccess redirect mod-rewrite https


【解决方案1】:

$_SERVER['HTTPS'] 始终为空,但当我在 https 页面上时,$_SERVER['HTTP_X_FORWARDED_PROTO'] 返回 https

这告诉您您的 SSL 由前端代理服务器管理,而不是您的应用程序服务器。您的应用程序服务器似乎没有安装 SSL 证书,并且很可能正在通过端口 80 向代理服务器提供纯 HTTP 请求。然后代理服务器将安全的 HTTPS 响应返回给客户端,因此客户端的请求是安全的。

这意味着如果您的应用服务器试图通过简单地检查标准服务器变量(即HTTPSSERVER_PORT)将HTTP重定向到HTTPS,那么这很可能会失败一个重定向循环,因为HTTPS 总是off 并且SERVER_PORT 总是 80 - 即使在重定向之后。 (请注意,HTTPS Apache 变量可能是“关闭”的,但这通常会转换为 PHP 超全局 $_SERVER['HTTPS'],即 - 这正是 PHP 处理它的方式。)

请注意,HTTP 到 HTTPS 的重定向可以在前端代理中执行,甚至在它到达应用程序服务器之前。 (Cloudflare 使用它的 页面规则来做到这一点。)

或者,您可以检查代理服务器设置的附加 HTTP 请求标头,因为请求从代理转发到您的应用程序服务器。 X-Forwarded-Proto 标头(由 PHP 存储为 $_SERVER['HTTP_X_FORWARDED_PROTO'])由代理服务器设置,并告诉您客户端用于连接代理的协议。

因此,将规范重定向放在一起:

# www to non-www redirect
RewriteCond %{HTTP_HOST} !^example\.com
RewriteRule (.*) https://example.com/$1 [R=301,L]

# http to https redirect
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

根据您发布的指令格式,应首先将 www 重定向到非 www 以避免在请求 http://www.example.com(即 HTTP 和 www)时出现双重重定向。

请注意,仅当您位于处理 SSL 的代理服务器后面时,才应使用这种类型的 HTTP 到 HTTPS 重定向。否则,X-Forwarded-Proto HTTP 请求标头可能会被恶意客户端请求伪造(不过,这应该由您的代理服务器处理)。


如果您愿意,这两条规则可以合并为一条规则:

# Canonical redirect (no-www and HTTPS)
RewriteCond %{HTTP_HOST} !^example\.com [OR]
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://example.com/$1 [R=301,L]

【讨论】:

  • 嗨!感谢您的详细回答,但它仍然显示相同的“重定向错误”错误
  • 如果解决方案不起作用,请尝试调试 PHP $_SERVER 变量以获得另一个标头,该标头显示 HTTPS 使用情况。在我的例子中是$_SERVER['HTTP_X_FORWARDED_PROTOCOL'],所以.htaccess 规则是# http to https redirect RewriteCond %{HTTP:X-Forwarded-Protocol} !https RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-11
  • 2014-10-08
  • 2013-09-08
  • 2012-11-07
  • 2017-07-18
  • 2012-11-02
相关资源
最近更新 更多