Sessions and subdomains

Hi there,

I’ve setup my new project like this (the Yii framework is some levels below):




/application/backend/..

/application/forums/..

/application/default/..

/web/backend/..

/web/forums/..

/web/www/..



Now, i’ve set up some subdomains like:




/web/www => http://www.my-project.loc/

/web/backend => http://backend.my-project.loc/

/web/forums => http://forums.my-project.loc/



When i login via http://www.my-project.loc, want to stay logged in when i go to http://backend.my-project.loc or http://forums.my-project.loc.

I’ve searched around the forums and the manual on this, but without result.

This may probably be a very stupid question, but this is a pain in the ass for me in the last 2 hours.

Before i forget to mention: i use CDbHttpSessions for session storage in database.

Thank you!

In config:




'components' => array(

   'session' => array(

      'class' => 'CDbHttpSession',

      'cookieParams' => array('domain' => '.my-project.loc'),

   ),

),



Now the session-cookie is available on all subdomains.

See here for API details. Please note that this currently doesn’t work with CWebUser::identityCookie. So if you use the auto-login feature of CWebUser you will run into trouble (not possible to logout anymore). Here is the related ticket, I expect a fix in Yii 1.1.2.

Thank you. (And thank you for mentioning the bug, you safe me from headaches :).

No problem. If you still want to use auto-login with working logout, you may try this lazy workaround I did some time ago:




class WebUser extends CWebUser

{


   public function logout($destroySession = true)

   {


      if ($this->allowAutoLogin && isset($this->identityCookie['domain']))

      {


         $cookies = Yii::app()->getRequest()->getCookies();


         if (null !== ($cookie = $cookies[$this->getStateKeyPrefix()]))

         {

            $originalCookie = new CHttpCookie($cookie->name, $cookie->value);

            $cookie->domain = $this->identityCookie['domain'];

            $cookies->remove($this->getStateKeyPrefix());

            $cookies->add($originalCookie->name, $originalCookie);

         }

			

      }		

		

      parent::logout($destroySession);


   }


}



Then in config you have to define the custom WebUser component:




'components' => array(

   'user' => array(

      'class' => 'application.components.WebUser',

      'allowAutoLogin' => true,

      'identityCookie' => array('domain' => '.my-project.loc'),

   ),

),



Thank you again ;).

Still,

When i login on www.project.loc.

And after that, go to backend.project.loc

A new session is being created. I checked it inside the database.

Is there a domain-dependent ‘salt’ used for the session id?

If I remember right it doesn’t cause any problems and it only happens under specific circumstances (can’t remember). At least everything should work like expected. Can’t say more about this, sorry. :mellow:

You can get a browser extension like firebug to see cookies being set. That should help you debugging this (if you want to).

[color="#696969"][size="2"](thanks to FireBug and FireCookie i discovered that i made an mistake on the sessions component configuration)[/size][/color]

Ok, so far i discovered that the user is logged in and no new sessions are being made anymore.

Everything seems to be working correctly.

However, the var [font="Courier New"][color="#696969"]Yii::app()->user->isGuest;[/color][/font]…

  • returns (a correct) [font="Courier New"][color="#696969"]false[/color][/font] on the subdomain where i logged in.

  • returns (a incorrect) [font="Courier New"][color="#696969"]true[/color][/font] on another subdomain.

When i refresh the page on another subdomain, i see that the session’s table [font=“Courier New”][color="#696969"]expire[/color][/font] field is begin updated.

So it looks like that something is going wrong here with the isGuest thing.

I will re-build your scenario and then post back.

Ok, thank you for your time! I appreciate it!

Hm I can’t reproduce. Are you using auto-login? Try to delete all cookies on all your domains and truncate session table. Then do a fresh test.

Also what I said about multiple session cookies was wrong. Actually there are 2 auto-login cookies when you delete the session cookie and then refresh the page. Though, it doesn’t cause any problems.

Yes, i am using auto-login.

Does it matter if i use the CDbAuthManager?

Thank you anyway.

No shouldn’t matter since it has nothing to do with the actual login/session.

Here my setup. You might try with this. If it doesn’t work something is wrong outside of Yii I guess.

From Controller:


		Yii::app()->session['test'] = rand(1,999999);

		

		if (!isset($_GET['login']))

		{

			if (Yii::app()->user->isGuest)

			{

				echo "guest";

			}

			else

			{

				echo "logged in";

			}			

		}

		else

		{


			$identity = new UserIdentity("test", "123456");

			

			if ($identity->authenticate())

			{

				Yii::app()->user->login($identity, 10000);

				echo "logged in now";

			}


		}

UserIdentity:


class UserIdentity extends CUserIdentity

{

	

	public $id;


	public function authenticate()

	{

		$this->id = 1;

		return true;

	}


	public function getId()

	{

		return $this->id;

	}


}

Config:




		'session' => array(

			'class' => 'CDbHttpSession',

			'connectionID' => 'db',

			'cookieParams' => array('domain' => '.example.com', 'lifetime' => 0),

			'timeout' => 3600,

			'sessionName' => 'session',

		),

		'user' => array(

			'allowAutoLogin' => true,

			'autoRenewCookie' => true,

			'identityCookie' => array('domain' => '.example.com'),

		),



Also there is only 1 session in the database.

This only works if i point all the [font="Courier New"]xxx.project.loc/index.php[/font] files to just one application.

[b]

when i set:[/b]

  • [color="#008080"][font="Courier New"]www.project.loc/index.php[/font][/color] to [color="#008080"][font="Courier New"]/application/www[/font][/color]

  • [color="#008080"][font="Courier New"]backend.project.loc/index.php[/font][/color] to [color="#008080"][font="Courier New"]/application/backend[/font][/color]

  • [color="#008080"][font="Courier New"]forums.project.loc/index.php[/font][/color] to [color="#008080"][font="Courier New"]/application/forums[/font][/color]

and add your controller code snippet into each individual controller:

[color="#008080"][font="Courier New"]/application/www/controllers/defaultController.php[/font][/color]

[color="#008080"][font="Courier New"]/application/backend/controllers/defaultController.php[/font][/color]

[color="#008080"][font="Courier New"]/application/forums/controllers/defaultController.php[/font][/color]

…it doesn’t seem to work.

However, it actualy works when i point all */index.php to the base app.

My Project setup is like

[color="#008080"][font="Courier New"]/application/@/…[/font][/color] [size="1"][color="#696969"]"Base app"[/color][/size]

[color="#008080"][font="Courier New"]/application/www/…[/font][/color] [size="1"][color="#696969"]"Includes (and overwrites only defined data of the) the config array from base app"[/color][/size]

[color="#008080"][font="Courier New"]/application/backend/…[/font][/color] [size="1"][color="#696969"]"Includes (and overwrites only defined data of the) the config array from base app"[/color][/size]

[color="#008080"][font="Courier New"]/application/forums/…[/font][/color] [size="1"][color="#696969"]"Includes (and overwrites only defined data of the) the config array from base app"[/color][/size]

-----------------------------------------------------------------------------------

[color="#008080"][font="Courier New"]/web/www/index.php[/font][/color] [size="1"][color="#696969"]"Includes the www app"[/color][/size]

[color="#008080"][font="Courier New"]/web/backend/index.php[/font][/color] [size="1"][color="#696969"]"Includes the backend app"[/color][/size]

[color="#008080"][font="Courier New"]/web/forums/index.php[/font][/color] [size="1"][color="#696969"]"Includes the forums app"[/color][/size]

Then the configs must be different in some way, but I guess you have session and user component defined in the config file under "base app"? Are you sure everything gets merged correctly?

[s]Yes well, here is an attachment of the projects root.

[/s]

/@ (the base) has indeed the session setup e.g.

I see you don’t use CMap::mergeArray to merge the config arrays. Can you please try it? I had some problems before when using custom merge function, maybe that’s the cause in some way.

To further debug save each merged config in a file and check if everything is like expected (compare each config file).

If you can not find error I will take a look on your uploaded skeleton tomorrow.

This was it!.. I’ll add an comment (done) on the custom array that was posted here. That was misleading me :(.

But now, the new config will NOT overwrite the old ones, mergeArray will only add new configuration settings if they were not setup in the base config.

The main problem is that when i change the application config variable ‘name’. I think the session id is using the application name?

Anyway, thanks for your time :).

I discovered that the problem has to do with the application name.

When i login on




return array(

	'name'=>'Application 1',

);



[font="Lucida Console"]Yii::app()->user->isGuest[/font] returns [font="Lucida Console"][color="#8B0000"]false[/color][/font]

When i open (it doesn’t matter if i use subdomains or not…)




return array(

	'name'=>'Application 2',

);



[font="Lucida Console"]Yii::app()->user->isGuest[/font] returns [font="Lucida Console"][color="#008000"]true[/color][/font]

When i change [font=“Lucida Console”]Application 2[/font] to [font=“Lucida Console”]Application 1[/font], both apps are returning [font=“Lucida Console”][color="#8B0000"]false[/color][/font]… and that’s correct.

Is there a solution for this? How to share sessions between different applications?

I’m not sure what’s exact problem here, but why not set everything to same application name? It’s obviously the same application anyway, just different areas like forum.

Have you thought about using modules instead of creating 3 separate applications?