1

我开发了一个 cakephp 网站,所有页面都应该使用 ssl。它按预期工作,除非我在控制器中使用重定向,它重定向到 http://subdomain.domain.com 而不是 https://subdomain.domain.com/controller/action。

我通过为指向 cakephp 应用程序的端口 80 创建一个虚拟主机解决了这个问题,并在 .htaccess 中添加了这些重写规则

RewriteCond %{HTTPS} 关闭 RewriteRule (.*) https://% {HTTP_HOST}%{REQUEST_URI} [L]

这会捕获这种情况并重定向到 https,但这会给服务器带来不必要的额外流量。

这种额外流量的原因是重定向功能,因为它会生成错误的 url。我研究了重定向功能,它调用 router::url 来创建实际的 url。但是我无法弄清楚如何或在哪里指示路由器使用 https 而不是 http。

蒂姆

4

3 回答 3

5

我猜测了一下,但我怀疑正是这个 RewriteRule 把事情搞砸了。

您应该“重定向”而不是“重写”。Cake 生成的链接通常是相对于根的,因此除非您将“true”作为第二个参数传递,否则不要指定协议。

我也让 apache 同时监听 80 和 443,这样我至少可以响应不正确的请求。

这是我在 AppController 类中执行相同操作的代码:

function beforeFilter() {
    parent::beforeFilter();
    $this->_setupSecurity();
}

function _setupSecurity() {
    $this->Security->blackHoleCallback = '_badRequest';
    if(Configure::read('forceSSL')) {
        $this->Security->requireSecure('*');
    }
}

/**
* The main SecurityComponent callback.
* Handles both missing SSL problems and general bad requests.
*/

function _badRequest() {
    if(Configure::read('forceSSL') && !$this->RequestHandler->isSSL()) {
        $this->_forceSSL();
    } else {
        $this->cakeError('error400');
    }
    exit;
}

/**
* Redirect to the same page, but with the https protocol and exit.
*/

function _forceSSL() {
    $this->redirect('https://' . env('SERVER_NAME') . $this->here);
    exit;
}

我在 bootstrap.php 中也有我自己的配置 'forceSSL' 选项,用于根据环境打开和关闭它,因此需要将其设置为 true 才能使上述工作。

于 2010-12-17T17:30:13.867 回答
0

我发现错误是 Apache 的错误配置。

尝试 Jamies 解决方案时,该站点以重定向循环结束,因为 RequestHandler->isSSL() 即使请求是 https 也返回 false。然后我发现 $_SERVER['https'] 没有设置,并且 $_SERVER['port'] 是 80,而不是预期的 443。

那时我已将我的 ssl 指令放在站点可用/默认中,

SSLEngine on
SSLCertificateFile [path to cert file]
SSLCertificateKeyFile [path to keyfile]

将 ssl 指令移至子域的虚拟主机通过重定向循环解决了该问题。

实际上也解决了我最初的问题,因为方法 Router::url 检查 $_SERVER['https'] 如果设置它会生成一个以 https: 开头的 url,否则只是 http:

我已经使用 .htaccess 中的重写规则测试了 Jameies 解决方案和我自己的解决方案,并且在修复后它们都按预期工作。

蒂姆

于 2010-12-19T15:20:53.907 回答
0

CookBook http://book.cakephp.org/2.0/en/core-libraries/components/security-component.html#usage中已经提到了它的示例

class AppController extends Controller {
    // Add security component
    public $components = array('Security');

    public function beforeFilter() {
        $this->Security->blackHoleCallback = 'forceSSL';
        $this->Security->requireSecure();
    }

    // Add this function in your AppController
    public function forceSSL() {
        return $this->redirect('https://' . env('SERVER_NAME') . $this->here);
    }
}
于 2014-11-19T05:44:46.060 回答