htaccess仅在特定的Zend Frameworks控制器/操作上重定向

时间:2011-07-05 08:58:45

标签: zend-framework .htaccess ssl url-rewriting ssl-certificate

我是这个社区的新手,但我发现它确实很有用。

我已经搜索了很多答案,但我找不到任何我需要的东西。我试图自己解决这个问题,但我仍然会遇到错误,所以我希望找到一个可以向我展示正确方法的人......: - )

我有一个“经典”的ZF网站,有许多控制器/动作网址,它们会重定向到带有.htaccess文件的index.php。

现在,我需要的是将两个控制器重定向到https ssl连接,不包括两个控制器的某些操作。

我试图这样做的方式是:


Options +FollowSymLinks

RewriteEngine on
RewriteBase /

RewriteCond %{HTTP_HOST} ^mydomain\.tld [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]

RewriteCond %{HTTPS} on
RewriteCond $1 ^!((member|shop)/(?!(index|login))(.*))
RewriteRule ^(.*) http://%{HTTP_HOST}/$1 [L,R=301]

RewriteCond %{HTTPS} off
RewriteCond $1 ^((member|shop)/(?!(index|login))(.*))
RewriteRule ^(.*) https://%{HTTP_HOST}/$1 [L,R=301]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !\.(js|ico|gif|jpg|png|css|swf|pdf|txt)$ index.php

当我去/成员控制器时似乎工作 但是,当我去另一个控制器时,例如/ index或/ about它不会重定向到http连接(端口80),如果我尝试改变一点重写条件正则表达式,它有时会做一个重定向循环和浏览器给我一个阻止与网站连接的通知。

是否有人能够在我的重写条件下向我显示正确的synthax以允许两个控制器(不包括给定的操作)在https连接下并在更改控制器时返回到标准的http连接?

提前致谢。

的Alessandro

4 个答案:

答案 0 :(得分:0)

请尝试使用这些规则(替换相应的行):

RewriteCond %{HTTPS} on [NC]
RewriteCond %{REQUEST_URI} !^/(member|shop)/ [NC]
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1 [L,R=301]

RewriteCond %{HTTPS} off [NC]
RewriteCond %{REQUEST_URI} ^/(member|shop)/ [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [L,R=301]
  1. 这些规则有点简单(HTTPS将应用于/member//shop/控制器中的所有网址(例如/member/login/member/dashboard/member/orders/15423/invoice等)
  2. 在RewriteCond指令中,否定! ^之前应 - 如果您需要自己的规则,请将RewriteCond $1 ^!((member|shop)/(?!(index|login))(.*))替换为RewriteCond $1 !^((member|shop)/(?!(index|login))(.*))

答案 1 :(得分:0)

我们用于重定向到https的方法是保留默认的Zend Framework .htaccess设置,并创建一个动作帮助程序,以便在需要时重定向到https。我们的行动助手代码是:

<?php
class RequireSSL extends Zend_Controller_Action_Helper_Abstract
{
    public function direct()
    {
        if(empty($_SERVER['HTTPS']) && $config['billing']['requireSSL'])
        {
            $redirector = $this->getActionController()->getHelper('Redirector');
            $redirector->goToUrlAndExit('https://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI']);
        }
    }
}

然后当您处于需要通过HTTPS访问的控制器操作中时,您只需在开头调用此函数:

$this->_helper->requireSSL();

此外,这是使用动作助手的另一种方法,如果需要,可以更详细一些:

http://juriansluiman.nl/en/article/110/in-control-of-https-for-action-controllers

希望有所帮助!

答案 2 :(得分:0)

我已经发现了问题的根源所在,但我仍然需要支持来了解如何解决问题。

我已经在本地linux机器上测试了htaccess,结果是相同的...分别测试两个https条件语句(打开和关闭)它们根据给定的RewriteCond正则表达式正确重定向。只组合从http到https的重定向工作。 http重定向的Https仅在正则表达式不匹配时才有效,否则重定向到http://www.mydomain.tld/index.php

所以我终于尝试删除最后一个htaccess语句并且它开始正常工作,但很明显,它找不到url,因为它不再重定向到index.php。

看起来在正确的https重定向后,index.php会产生问题。所以我问自己是否有办法避免这种情况并使其正常工作。

正如我之前写的,这似乎是这个htaccess的常见问题,因为它在测试和生产服务器上的行为是相同的(不同的linux风格)。

我把工作代码放在这里:


Options +FollowSymLinks

RewriteEngine on
RewriteBase /

#RewriteCond %{HTTP_HOST} ^mydomain\.tld [NC]
#RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]

RewriteCond %{HTTPS} on
RewriteCond $1 !^((member|shop)/(?!(index|login))(.*))
RewriteRule ^(.*) http://%{HTTP_HOST}/$1 [L,R=302]

RewriteCond %{HTTPS} off
RewriteCond $1 ^((member|shop)/(?!(index|login))(.*))
RewriteRule ^(.*) https://%{HTTP_HOST}/$1 [L,R=302]

#RewriteCond %{REQUEST_FILENAME} !-f
#RewriteRule !\.(js|ico|gif|jpg|png|css|swf|pdf|txt)$ index.php

答案 3 :(得分:0)

最后我解决了!我坚持不懈地寻找答案,因为我觉得用.htaccess做这件事更干净,更聪明,更容易维护。 问题主要是由于“ssl到非ssl”块中使用的正则表达式没有正确匹配传递的值(现在最好匹配env变量%{THE_REQUEST},在某些情况下避免了错误重定向循环。

我在这里粘贴工作代码以供进一步参考:


    Options +FollowSymLinks

    RewriteEngine On

    RewriteBase /

    RewriteOptions MaxRedirects=1



    RewriteCond %{HTTP_HOST} ^yoursite\.tld [NC]

    RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]



    RewriteCond %{HTTPS} off

    RewriteCond %{THE_REQUEST} ^[A-Z]+\ /((controller1|controller2)/(?!(action1|action2))(.*))\ HTTP/

    RewriteRule ^(.*)$ https://%{SERVER_NAME}/$1 [L,R=301]



    RewriteCond %{HTTPS} on

    RewriteCond %{THE_REQUEST} !^[A-Z]+\ /((controller1|controller2)/(?!(action1|action2))(.*))\ HTTP/

    RewriteRule ^(.*)$ http://%{SERVER_NAME}/$1 [L,R=301]



    RewriteCond %{REQUEST_FILENAME} \.(js|css|ico|gif|jpg|png|swf|txt|pdf)$ [OR]

    RewriteCond %{REQUEST_FILENAME} -s [OR]

    RewriteCond %{REQUEST_FILENAME} -l [OR]

    RewriteCond %{REQUEST_FILENAME} -d

    RewriteRule ^.*$ - [NC,L]



    RewriteCond %{REQUEST_FILENAME} !-f

    RewriteCond %{REQUEST_FILENAME} !-d

    RewriteRule ^.*$ index.php [NC,L]