Question

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?

Was it helpful?

Solution

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:

  • You're redirecting to the same URL but for the protocol, no point in redundantly generating the URL
  • The decision of whether a particular controller gets redirected lives with the controller; this gets more important as you get to the point (and you likely will get to the point) where it's not just per-controller but per-action

OTHER TIPS

Why let it get to the application? Use htaccess rewrites if you are cathcing specific routes to force ssl.

Ssl is a transmission protocol detail and has nothing to do with your site code, let apache (or nginx) handle those details. Separation of responsiblity to what best to handle things.

If you provide exac urls you want to catch I am sure somone could help with the rewrite condition logic

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top