Sharing Sessions across multiple web applications

I am working on creating a single sign on type of application for my development server that will make it easier to work on other applications while they are in development. These are all web applications.

My directory structure is as follows:




Application1 (single sign on)

  assets

  css

  images

  js

  protected

  

  ApplicationA

  ApplicationB

  ApplicationC



Each of the “child” Applications A, B & C will eventually be moved to their own fully independent live servers. This means that each child application also has it’s own user control and session management when live. Whatever changes I make for this single sign on need to be easily changeable for when the child application is moved live.

So far my approach has been to setup two different session config files, one that has the details of the “parent” single sign on application and one that will use the child applications’ details. Then in each of the index files for the applications I have setup an array merge. This way I can simply change the session include file in each application when it is moved live to point to the live version.

Child Application index file:




<?php

require(dirname(__FILE__).'/../../Yii/framework/yii.php');

$local = require('/protected/config/front.php');


$session = require('/protected/config/session_dev.php'); // change to session.php for live


$config = CMap::mergeArray($local, $session);


Yii::createWebApplication($config)->runEnd('front');



session_dev.php contains the details that are used in the session and database parameters of App1.




<?php

$dbHost = 'dbHost';

$dbName = 'dbName';

$dbUsername = 'dbUser';

$dbPassword = 'dbPass';


$connectionString = 'mysql:host='.$dbHost.';dbname='.$dbName;


return array(

// store sessions in the database

	'components'=>array(

		'user'=>array(

			// enable cookie-based authentication

			'allowAutoLogin'=>true,

		),

		

		'db_dev'=>array(

			'connectionString' => $connectionString,

			'emulatePrepare' => true,

			'username' => $dbUsername,

			'password' => $dbPassword,

			'charset' => 'utf8',

			'enableProfiling' => true,

			'enableParamLogging' => true,

		),

		

		'session' => array(

			'autoStart' => true,

			'class' => 'system.web.CDbHttpSession',

			'connectionID' => 'db_dev',

			'cookieMode' => 'allow',

			'cookieParams' => array(

				'path' => '/',

				'domain' => 'localhost',

				'httpOnly' => true,

			),

		),

	),

	'behaviors' => array(

		'onBeginRequest' => array(

			'class' => 'application.components.RequireLogin'

		)

	),

);




Additionally the "id" parameter in the main config of each application have all been set to the same thing.

The single sign on application (App1) has a frontend and backend (both with logins) and I can access both successfully after logging into either one.

According to what I’ve read in various posts this should be working so that once a user has logged into App1 they will automatically be logged into AppA, B & C because they all are on the same domain. However this is not the case.

print_r(Yii::app()->session); returns nothing in the “child” applications. I have confirmed that the child apps are not using their own database session tables but I can’t seem to access the existing logged in session.

Thanks,

Jay

Did you extend CWebUser and set the identityCookie attributes to be the same as in your main config file?

I have added the following from this tutorial but there was no change in behaviors.

protected/components/WebUser.php




<?php

class WebUser extends CWebUser

{

    public function init()

    {

        $conf = Yii::app()->session->cookieParams;

        $this->identityCookie = array(

            'path' => $conf['path'],

            'domain' => $conf['domain'],

        );

        parent::init();

    }

}



To be honest though I’m not quite sure how it is getting accessed. I don’t find any calls to CWebUser that I would change to WebUser. Where would I typically find those?

Thank you,

Jay

Do you mean where to set it? In the components section of your config file, you would set the user class to be ‘WebUser’ in your case.




'components'=>array(

    'user'=>array(

      'class'=>'WebUser',

    ),

),



I found this post looking for a solution for the same issue. None of the post related to the given solution. In the end, looking at the code I found that session variables depend CWebuser :: getStateKeyPrefix which in turn depends on CApplication :: getId () which is generated automatically from CApplication :: getBasePath ()

then, for two applications (with different basepath) share sessions, must have the same application id because session variables are encoded with this id. In both config / main.php must be set the same id

in app1




return array (

.....

'name' => 'app1'

'id' => 'myapp'

...



in app2


return array (

.....

'name' => 'app2'

'id' => 'myapp'

...



it worked for me, hope it help