I'd like to force SSL for certain controllers, and remove SSL for everything else. I had a snippet some time ago in the _init() of a custom Controller class, it didn't work as I had hoped:
$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://')
)
);
}
I'm supporting a legacy application, so I've got multiple hard-coded routes defined. I'm sure that I could use a handler in the Router::connect, but I'd rather do the check on all requests. Would continuation routes be the way to go here?
Two things: (1) you can't return a Response
object from _init()
(which is what redirect()
returns), and (2) you have a subtle design problem. I'd suggest doing it like this:
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://'
]));
}
Observations: