2017-09-20 33 views
3

我试图强制所有的网站都https。所以我做了:Htaccess强制https除了在一个网址上不起作用

RewriteEngine On 
RewriteBase/
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule .* index.php 

RewriteCond %{HTTP:X-Forwarded-Proto} =http [OR] 
RewriteCond %{HTTP:X-Forwarded-Proto} ="" 
RewriteCond %{HTTPS} !=on 
RewriteRule^https://%{HTTP_HOST}%{REQUEST_URI} [L,R=302] 

它的工作原理。问题是我希望mywebsite.com/api/...上的http调用也可以工作。所以我加RewriteCond %{REQUEST_URI} !^/api(/.*)?

我的.htaccess是:

RewriteEngine On 
RewriteBase/
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule .* index.php 

RewriteCond %{HTTP:X-Forwarded-Proto} =http [OR] 
RewriteCond %{HTTP:X-Forwarded-Proto} ="" 
RewriteCond %{HTTPS} !=on 
RewriteCond %{REQUEST_URI} !^/api(/.*)? 
RewriteRule^https://%{HTTP_HOST}%{REQUEST_URI} [L,R=302] 

但它不工作。如果我打电话http://mywebsite.com/api/xxx它会将我重定向到https://mywebsite.com/index.php ..

我不知道为什么。你有什么想法?
我使用的Zend 1

---- ----编辑

改变了我的.htaccess这样:

RewriteEngine On 

# HTTPS 
RewriteCond %{HTTPS} !=on 
RewriteCond %{REQUEST_URI} !^/api(/.*)? 
RewriteRule^https://%{HTTP_HOST}%{REQUEST_URI} [L,R=302] 

RewriteBase/
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule .* index.php 

Options +Indexes 
IndexIgnore * 

但仍然无法正常工作

--- - 编辑2 ----

新的.htaccess(这一个工作):

RewriteEngine On 
RewriteBase/

# HTTPS 
RewriteCond %{HTTP:X-Forwarded-Proto} =http [OR] 
RewriteCond %{HTTP:X-Forwarded-Proto} ="" 
RewriteCond %{HTTPS} !=on 
RewriteCond %{REQUEST_URI} !^/api 
RewriteCond %{QUERY_STRING} !^/api 
RewriteRule^https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] 

RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule ^(.*)$ index.php?/$1 [NC,L,QSA] 

我不得不与QUERY_STRING添加条件,改变过去重定向到index.php

谢谢@MrWhite

+0

你是在代理服务器后面吗? – MrWhite

+0

@MrWhite nop,而不是代理 – RichardLenoir

回答

4

你在错误的顺序指令。您的规范HTTP到HTTPS重定向应该在您的内部重写之前(即您的前端控制器)。否则,/api/<something>的请求将被内部重写为/index.php(因为我假设/api/<something>不作为真实文件存在)。 /index.php然后将不匹配您的RewriteCond指令,该指令正在检查/api/<something>。所以你然后重定向https://example.com/index.php(虽然你在你的例子中给出http?)。

不使用代理

如果你不使用代理服务器,那么你应该删除检查X-Forwarded-Proto HTTP请求头(这些只能通过代理服务器设置的条件,如果您不是在代理服务器后面,那么客户端可能会恶意设置此标头并避免重定向)。

这两条线:

RewriteCond %{HTTP:X-Forwarded-Proto} =http [OR] 
RewriteCond %{HTTP:X-Forwarded-Proto} ="" 

UPDATE:如果你删除上述条件后重定向循环,那么它可能是你背后的SSL代理毕竟(你应该可以通过检查你的应用程序看到的HTTP请求头来判断 - 你不一定需要访问服务器配置 - 事实上,你可能无法通过查看服务器配置来判断)。

(当你落后的SSL代理,那么HTTPS总是off - 您的应用程序用于SSL代理是再提供一个加密的HTTP响应返回给客户端的HTTP响应。)

尝试以下操作:

Options +Indexes 
IndexIgnore * 

RewriteEngine On 
RewriteBase/

# HTTP to HTTPS, except for the api subdirectory 
RewriteCond %{HTTP:X-Forwarded-Proto} =http [OR] 
RewriteCond %{HTTP:X-Forwarded-Proto} ="" 
RewriteCond %{HTTPS} !=on 
RewriteRule !^api https://%{HTTP_HOST}%{REQUEST_URI} [L,R=302] 

# Front controller 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule .* index.php [L] 

请注意,这不是canonicalise www与非www。

+0

谢谢。我尝试更改顺序,并将HTTP重定向到HTTPS,但问题仍然存在。 – RichardLenoir

+0

确保您清除了浏览器缓存。你所看到的重定向表明指令是相反的。 – MrWhite

+0

编辑我的.htaccess到'RewriteCond%{HTTP} = RewriteCond%{REQUEST_URI}!^/api(/.*)? RewriteRule^https://%{HTTP_HOST}%{REQUEST_URI} [L,R = 302]',并改变顺序,但它仍然不起作用(编辑我的问题) – RichardLenoir

1

不管你的代码,只放下面的代码在你的主目录.htaccess文件:

RewriteEngine On 
RewriteCond %{HTTPS} !=on 
RewriteCond %{THE_REQUEST} !\s/+api/ [NC] 
RewriteRule^https://%{HTTP_HOST}%{REQUEST_URI} [L,R] 

这将迫使所有的要求,除了api/https那么如果你要求yourwebsite/API与httphttpwww或没有www它会去api/目录,因为它不是api/问题来与有或没有https以及www和上述规则将适用于没有https因为这种情况RewriteCond %{HTTPS} !=on因此,如果它来覆盖此规则,它将覆盖thi规则,并且为什么http://yourwebsite/apihttps://yourwebsite/api将工作

+0

但是,看起来OP可能在SSL代理之后(因此需要检查'HTTP:X-Forwarded-Proto'而不是'HTTPS')。当OP尝试类似的时候,他们得到了一个重定向循环(参见另一个答案的评论)。 – MrWhite

+0

最后,你是对的,但是当你先问他时,他说“不” –