2012-10-29 57 views
1

我想强制某些控制器的SSL,并删除SSL的一切。我在一个自定义的控制器类的_init()有一个片段,前一段时间,我曾希望它不工作:为某些控制器强制使用SSL的最佳方法?

$ssl = $this->request->is('ssl'); 

$forceSecured = in_array($this->request->controller, array('Orders', 'Customers')); 

//remove SSL for non-ssl pages 
if ($ssl && !$forceSecured) { 
    return $this->redirect(Router::match(
        $this->request->params, 
        $this->request, 
        array('absolute' => true, 'scheme' => 'http://') 
      ) 
    ); 
} 

// Force ssl on for ssl pages 
if (!$ssl && $forceSecured) { 
    return $this->redirect(Router::match(
        $this->request->params, 
        $this->request, 
        array('absolute' => true, 'scheme' => 'https://') 
      ) 
    ); 
} 

我支持遗留应用程序,所以我有多个硬盘已编码的路线已定义。我确信我可以在Router :: connect中使用一个处理程序,但我宁愿对所有请求进行检查。延续路线是否会成为这里的路?

回答

3

两件事情:(1)你不能从_init()返回Response对象(这是什么redirect()回报),和(2)你有一个微妙的设计问题。我建议做这样的:

protected $_secure = false; 

public function __invoke($request, $params, array $options = array()) { 
    if (!$this->_secure && !$request->is('ssl')) { 
     return parent::__invoke($request, $params, $options); 
    } 
    return $this->redirect(Router::match($request->url, $request, [ 
     'absolute' => true, 'scheme' => 'https://' 
    ])); 
} 

观察:

  • 你重定向到相同的URL,但该协议,在冗余产生的URL没有点
  • 的决定一个特定的控制器是否被重定向与控制器共存;因为你到了点(你可能去点),它不只是每个控制器,但每次动作
+0

返回'Response'对象是我陷入困境的地方。另外,我想我没有把它抽象出来。 注意,'$ this-> redirect line'缺少一个右括号。 –

+0

那里,我修好了。 –

0

为什么让它进入应用程序?如果您正在使用特定路由强制ssl,请使用htaccess重写。

Ssl是一个传输协议细节,与您的站点代码无关,让apache(或nginx)处理这些细节。将责任分离到最好的处理事物。

如果您提供的网址EXAC你想赶上我相信有人为可以与重写条件逻辑帮助

+1

我同意这种说法有点,但想想链接生成这个变得更重要和反向路由。应用程序输出重定向或http链接时效率不高,这些重定向或http链接必须由Web服务器再次重定向。 – rmarscher

+0

@rmarscher当应用程序发出30x重定向时,它仍然是另一个请求往返。我说完全切断应用程序,并让它由apache完成,然后应用程序才看到它永远不会路由它。 – Ray

+0

不同意。是否确保页面的决定是一项商业决策。 (1)重写规则不提供能够用商业术语表达的抽象,(2)你已经有了一个业务逻辑的地方:控制器;为什么把它分开?您谈论的优化级别很少是一个有效的关注点。 –

相关问题