【问题标题】:Rewrite http to https and viceversa with .htaccess使用 .htaccess 将 http 重写为 https,反之亦然
【发布时间】:2013-12-27 06:54:09
【问题描述】:

我想用 Zend Framework 将所有 URL 重写为 SSL,但特定文件夹/控制器除外。例如,我想从 SSL 中排除身份验证控制器,然后如果我访问https://blabla.com/auth,我想重写为http://blabla.com/auth

我在htaccess https redirect only on specific Zend Frameworks controller/actionsRewrite all URL to SSL except specific folders with Zend Framework 中尝试了一些代码,但没有任何效果。

现在这是我在 .htaccess 文件中的代码。有什么建议吗?

RewriteEngine On

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

RewriteCond %{HTTPS} off [NC]
RewriteCond %{REQUEST_URI} ^/(auth|client)/ [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [L,R=301]

RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [L]

更新

它不会引发任何错误,但是当我使用 http 访问页面时,它会将我重定向到使用 https 的索引页面:

RewriteEngine On

#If HTTPS is off and this is not /auth or /client - redirect to https
RewriteCond %{HTTPS} off
RewriteCond $1 !^(en/x/auth/index) [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R,L]

#If HTTPS is off and this is /auth or /client - redirect to http
RewriteCond %{HTTPS} on
RewriteCond $1 ^(en/x/auth/index) [NC]
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1 [R,L]

RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]

【问题讨论】:

  • 验证时不使用加密有意义吗?
  • 使用你的 apache/virtualhost 配置文件。
  • 是的,斯文,这没有意义,但我只是一个例子

标签: php .htaccess zend-framework ssl https


【解决方案1】:

不需要更改 .htacess 中的某些内容,只需创建一个插件控制器

控制器插件

namespace Custom\Controller\Plugin;

class Ssl extends \Zend_Controller_Plugin_Abstract
{

    /**
     * Check the application.ini file for security settings.
     * If the url requires being secured, r ebuild a secure url
     * and redirect.
     *
     * @param Zend_Controller_Request_Abstract $request
     * @return void
     * @author Travis Boudreaux
     */
    public function preDispatch(\Zend_Controller_Request_Abstract $request)
    {
        $shouldSecureUrl = false;

        $options = new \Zend_Config_Ini(APPLICATION_PATH . '/configs/ssl.ini');
        $options = $options->ssl;

        //if config is empty, exit
        if (!is_object($options))
            return;

         //simpler to use
         $options = $options->toArray();

        if (APPLICATION_ENV == 'production') {

            if ($request->controller == 'ajax')
                return;

            //check configuration file for one of three require_ssl directives
            //secure an entire module with modules.module_name.require_ssl = true
            //secure an entire controller with modules.module_name.controller_name.require_ssl = true
            //secure an action with modules.module_name.controller_name.action_name.require_ssl = true
            if (isset($options['modules'][$request->module][$request->controller]['require_ssl'])
                    && ($options['modules'][$request->module][$request->controller]['require_ssl'])
            ) {
                $shouldSecureUrl = true;
            } elseif (isset($options['modules'][$request->module][$request->controller][$request->action]['require_ssl'])
                    && ($options['modules'][$request->module][$request->controller][$request->action]['require_ssl'])
            ) {
                $shouldSecureUrl = true;
            } elseif (isset($options['modules'][$request->module][$request->controller][$request->action]['require_ssl'])
                    && !($options['modules'][$request->module][$request->controller][$request->action]['require_ssl'])
            ) {
                $shouldSecureUrl = false;
            }

            if (empty($shouldSecureUrl))
                $shouldSecureUrl = false;

            $this->_setupUrls($request, $shouldSecureUrl);
        }
    }

    /**
     * Check the request to see if it is secure.  If it isn't
     * rebuild a secure url, redirect and exit.
     *
     * @param Zend_Controller_Request_Abstract $request
     * @param boolean $secure_url
     * @return void
     * @author Travis Boudreaux
     */
    protected function _setupUrls(\Zend_Controller_Request_Abstract $request, $secure_url)
    {
        $server = $request->getServer();
        $hostname = $server['HTTP_HOST'];

        if ($request->isSecure()) {
            if (!$secure_url) {
                $url = \Zend_Controller_Request_Http::SCHEME_HTTP;
                $url .= '://' . $hostname . $request->getRequestUri();

                $redirector = \Zend_Controller_Action_HelperBroker::getStaticHelper('redirector');
                $redirector->setGoToUrl($url);
                $redirector->redirectAndExit();
            }
        } else {
            if ($secure_url) {
                $url = \Zend_Controller_Request_Http::SCHEME_HTTPS;
                $url .= '://' . $hostname . $request->getRequestUri();

                $redirector = \Zend_Controller_Action_HelperBroker::getStaticHelper('redirector');
                $redirector->setGoToUrl($url);
                $redirector->redirectAndExit();
            }
        }
    }
}

ssl.ini 可以保存在 APPLICATION_PATH 中。 '/configs' 目录

ssl.modules.default.register.require_ssl = true
ssl.modules.default.login.require_ssl = true
ssl.modules.default.dashboard.require_ssl = true
ssl.modules.default.payment.require_ssl = true
ssl.modules.default.password.require_ssl = true
ssl.modules.default.profile.require_ssl = true

ssl.modules.admin.login.login.require_ssl = true
ssl.modules.admin.dashboard.require_ssl = true
ssl.modules.admin.payment.require_ssl = true
ssl.modules.admin.password.password.require_ssl = true
ssl.modules.admin.password.forgot.require_ssl = true
ssl.modules.admin.publicateur.require_ssl = true
ssl.modules.admin.profile.require_ssl = true

最后在你的引导程序中注册插件

/* other bootstrap config above */
protected function _initPlugin()
{
    $front = Zend_Controller_Front::getInstance();

    $front->registerPlugin(new Ssl());
}

【讨论】:

  • 感谢 Travis Boudreaux。还有一件事你不能摆脱控制器插件中的命名空间并将类重命名为你的套装并通过引导程序中的注册名称希望它有所帮助来更正
  • @sparkling 它是 zf2 中的 zf1,您不会以这种方式注册插件,也没有更多的引导类!如果命名空间让你感到困惑,你不能摆脱它并给另一个类名!
  • 非常感谢马塞尔,它就像一个魅力!我稍微修改了代码以默认启用 ssl,但 ssl.ini 文件中的控制器/操作除外。使用 .htaccess 的所有其他尝试都失败了。
  • @sparkling 欢迎您。很高兴看到它有帮助。我意识到我的示例在 ssl.ini 中不够精确。我会尝试找到原始博客文章,它可以帮助其他人。
【解决方案2】:

我想,你把条件弄错了。我试图重写:

#If HTTPS is off and this is not /auth or /client - redirect to https
RewriteCond %{HTTPS} off
RewriteCond $1 !^(auth|client) [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [L,R=301]

#If HTTPS is off and this is /auth or /client - redirect to http
RewriteCond %{HTTPS} on
RewriteCond $1 ^(auth|client) [NC]
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1 [L,R=301]

【讨论】:

  • 我累了,但我不能让它工作......协议没有改变,它总是https
  • @sparkling 如果您在这些之前有任何其他规则,请将其删除。你试试https://site.com/auth/blah-blah
  • 我在这些之后(而不是之前)有其他规则(就像在第一个示例中一样),所以我需要它将所有规则重定向到 index.php(我正在研究 Zend Framewrok)。是的,我试过site.com/auth/blah-blah。似乎请求 uri 条件没有像我们预期的那样工作......
  • 好的,非常感谢@user5035,现在不会抛出任何错误,但是当我访问没有 https 访问的页面(身份验证控制器)时,它会将我重定向到带有 https 的主索引。我在原始答案中编辑了我当前的代码。
  • @sparkling 在这种情况下,我不明白,你想要什么。您在更新中写了 2 个步骤: 1. 如果协议不是 https 并且页面不是 /en/x/auth/index - 重定向到 https。 2. 将任何页面重定向到 index.php - 最后一个重写规则。删除最后一条规则,它不会将任何页面重定向到索引。
猜你喜欢
  • 2012-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-04
  • 2017-01-26
  • 1970-01-01
  • 2021-12-28
相关资源
最近更新 更多