How to easily redirect/create urls for separate secure subdomain

Hi,

The site I’m working on uses a separate subdomain for https traffic as in:

http uses www.domain.com

https uses secure.domain.com

this means I can’t just neatly set the scheme to https when I use any of the url creation methods, because then it will go to https://www.domain.com, not https://secure.domain.com

I thought about making a sub class of \yii\helpers\Url, and just having it switch the domain name when https is passed as a scheme, but I’m daunted by the many different ways to create urls

Url::to

Url::routeTo

Url::createAbsoluteURL

etc…

So… just throwing this out there - anyone else dealt with this problem?

I think I’ll just create an alias @secure for https://secure.domain.com and then explicitly send people there when I need to.

Just wondering if there’s a more elegant solution.

-Charlie

You could just have your sub-domain point to the domains root and install the ssl on the sub-domain. You’d need to make sure that all of your assets i.e. images, css, js, etc also get called via your sub-domain or you will get invalid sll cert errors. you would also need to make sure your routes get handled via https

here is an example i got somewhere base controller to extend other controllers from




<?php


namespace common\components;


use Yii;


class Controller extends \yii\web\Controller {


	public function beforeAction($action) {

    	if (Yii::$app->request->enableSslRoutes) {

        	/**

     		* This piece of code here is to allow partial SSL for the minute while we cannot fully use SSL all over the site

     		*/

        	$found = false;

        	foreach (Yii::$app->request->sslRoutes as $route) {

            	if ($route == Yii::$app->controller->id . '/' . Yii::$app->controller->action->id) {

                	$found = true;

                	if (!Yii::$app->request->getIsSecureConnection() && !isset(error_get_last()['type'])) {

                    	$sslUrl = Yii::$app->getUrlManager()->createAbsoluteUrl(Yii::$app->request->absoluteUrl, 'https');

                    	return Yii::$app->controller->redirect($sslUrl)->send();

                	}

            	}

        	}


        	if (

                	Yii::$app->request->getIsSecureConnection() &&

                	!$found &&

                	(Yii::$app->controller->id . '/' . Yii::$app->controller->action->id !== 'site/error')

        	) {

            	$httpUrl = Yii::$app->getUrlManager()->createAbsoluteUrl(Yii::$app->request->absoluteUrl, 'http');

            	return Yii::$app->controller->redirect($httpUrl)->send();

        	}

    	}

    	return parent::beforeAction($action);

	}

}

here is a request handler too




<?php


namespace common\components;


use Yii;


class Request extends \yii\web\Request {


	/**

 	* By default CSRF will be turned on but disabled for all actions.

 	* This will turn Allow CSRF to run on certain actions, for example put add "user/login" as

 	* an element in this array to have CSRF run there

 	*/

	public $csrfRoutes = [];

	public $enableSslRoutes = true;


	/**

 	* For a site that is not completely SSL you define SSL routes, i.e.: site/login

 	*/

	public $sslRoutes = [];


	public function validateCsrfToken() {

    	if (

            	$this->enableCsrfValidation &&

            	!in_array(Yii::$app->getUrlManager()->parseRequest($this)[0], $this->csrfRoutes)

    	) {

        	return true;

    	}

    	return parent::validateCsrfToken();

	}


}



frontendconfig




return [

	'id' => 'app-frontend',

	'name' => 'GeekObjects',

	'basePath' => dirname(__DIR__),

	'bootstrap' => ['log'],

	'controllerNamespace' => 'frontend\controllers',

	'components' => [

    	'request' => [

        	'class' => 'common\components\Request',

        	'enableCsrfValidation' => true,

        	'csrfRoutes' => [

            	'site/login',

            	'site/signup',

            	'site/request-password-reset',

            	'site/reset-password',

            	'site/confirm-login'

        	],

        	'cookieValidationKey' => $params['request.cookieValidationKey']

    	],


---other config settings----



Maybe this will point you in the right direction and you would need to configure it properly and place the files were you want.

thanks skworden.

It looks like that code will nicely redirect any http request to https if the request is made to a set of "https" only urls.

That’s great, I may make use of it. But I was hoping for something that would elegantly swap in the correct subdomain - the line above just adds https to the main (insecure) subdomain).

right now, I’m leaning toward subclassing Url and UrlManager and overriding methods so they return the appropriate subdomain, stored in an aliases. Something like this for the Url::to method, for example. But Yii has so many different url generating functions that all work a bit differently, i’ll have to do it for several methods, if I want to be thorough.

For now here’s my Url::to where @secure and @insecure are defined as empty string in the main.php config file and then can be set to secure.domain.com and www.domain.com in main-local.php (so I can work locally on using “local” domains).





use Yii;


class Url extends \yii\helpers\Url

{


    static public function to($url = '', $scheme = false)

    {

        if ($scheme === 'https' && Yii::getAlias('@secure', false)) {

            $url = parent::to($url);

            return Yii::getAlias('@secure').$url;

        } else if ($scheme === 'http' && Yii::getAlias('@insecure', false)) {

            $url = parent::to($url);

            return Yii::getAlias('@insecure').$url;

        } else {

            return parent::to($url, $scheme);

        }

    }


}



seem like an ok solution?