0

I'm re-building a web application in CakePHP 3 and plan to change how the application is structured. At the moment the architecture is as follows - and none of it is written in Cake.

There is a login page at https://app.example.com which sets PHP session variables on successful login. All of the applications are then in sub-directories, e.g.

https://app.example.com/application-1
https://app.example.com/application-2
https://app.example.com/application-3

Each sub-directory has a script which checks the appropriate session vars are set, otherwise redirects to the login page, e.g. trying to access https://app.example.com/application-1 without being logged in sends the user to https://app.example.com/

I'm planning to rebuild one of the applications, https://app.example.com/application-2 in CakePHP 3, and do so on a separate subdomain (e.g. https://cake.example.com/).

What I want to do is allow the users to still login through https://app.example.com and then use https://cake.example.com/ if they are succesfully authenticated.

I was planning to allow my PHP sessions to work across multiple subdomains - as per Allow php sessions to carry over to subdomains

I'm not sure though how this would work within Cake 3 though. One idea I had was to set up https://cake.example.com/ without any of Cake's Auth functionality enabled. I was then going to use the AppController::beforeFilter() to check the session variables. If they were set appropriately, allow the user to use any Cake Controller method. If not, redirect them to https://app.example.com where they can login.

I was looking for some advice on whether there is a better way to do this, and if this is secure? I'm aware that doing this is essentially like developing the Cake app with no authentication, and just relying on the session vars being read in beforeFilter().

The login script at https://app.example.com also writes to a database where we have things such as the user ID, IP, user agent string and date/time. I can access this DB from my Cake application, but the idea of querying this database on every single request also seems wrong.

It's worth mentioning that https://cake.example.com cannot have it's own login page, even if it connected to the existing users database to lookup the credentials. This is because the users login through https://app.example.com which then acts as a dashboard for their applications. Essentially by the time they get to https://cake.example.com they either have to be authenticated, or sent back to the existing login page.

Community
  • 1
  • 1
Andy
  • 5,142
  • 11
  • 58
  • 131
  • Will REST Api or cURL can help? ref this http://stackoverflow.com/questions/3008817/login-to-remote-site-with-php-curl – Shashikala May 08 '17 at 11:54
  • What exactly does the auth info data structure look like that your login app writes to the session? – ndm May 08 '17 at 11:58
  • http://stackoverflow.com/questions/30781345/is-it-possible-to-login-into-cake-php-app-from-yii-app...i think this is similar to your issue – Shashikala May 08 '17 at 12:04
  • @ndm it simply writes things like the user ID and user agent string into global `$_SESSION` variables... – Andy May 08 '17 at 13:03
  • I suspected something like that, but the exact structure is important, as it determines whether you could easily utilize CakePHP auth functionality, hence I'm asking. – ndm May 08 '17 at 13:12
  • @ndm I doubt it would be one Cake could just use because it was never written with Cake in mind. The only vars I can see are one called `$_SESSION['u_id']` for the user ID, and another `$_SESSION['useragent']` for the user agent string. Are there any docs on what Cake would require for a function to work with Auth? – Andy May 08 '17 at 13:38

1 Answers1

2

Checking the session manually can be just as secure as using CakePHPs auth component, as the component does exactly the same (given that you'd be using the session storage), just with data that you've set via AuthComponent::setUser(), ie it all depends on whether you implement things properly.

Checking the session value in AppController::beforeFilter(), and redirecting if necceesary should generally be fine, and as mentioned is pretty much the same as what the auth component does internally, it will check whether the configured session key is present and not empty.

You could possibly still leverage the CakePHP auth functionality if you wanted to, the flat u_id value in the session should suffice. For the auth component, just configure the login/logout options and the session storage key accordingly, ie if your login page is at https://app.example.com, and your login app writes auth data to $_SESSION['u_id'], configure the auth component like this:

$loginUrl = 'https://app.example.com';

$this->loadComponent('Auth', [
    'loginAction' => $loginUrl,
    'loginRedirect' => $loginUrl,
    'logoutRedirect' => $loginUrl,
    'storage' => [
        'class' => 'Session',
        'key' => 'u_id'
    ]
]);

That should be all that is needed (authentication wise), the component should pick up the possibly existing session key and treat you as authenticated, or otherwise redirect to https://app.example.com. Defining loginAction will prevent the component from whitelisting a controller/action, and logoutRedirect will be returned by AuthComponent::logout(), so you could easily implement a standard logout action in your CakePHP app if you want/need.

Of course this all depends on the u_id session value being accessible (ie you've configured your CakePHP app to pick up the existing session) and reliable in the first place.

ndm
  • 59,784
  • 9
  • 71
  • 110
  • Thank you for this, excellent advice. The issue I'm facing now is where you've said "depends on the u_id session value being accessible" - I cannot access any of the `$_SESSION` data set by `https://app.example.com` on `https://cake.example.com` even though I've followed the bit about setting `session.cookie_domain` (https://book.cakephp.org/3.0/en/development/sessions.html#session-configuration) – Andy May 08 '17 at 14:59
  • @Andy The `session.cookie_domain` ini config only affects writing cookies, for being able to read them make sure that you've configured the cookie name properly, ie the `cookie` option (defaults to `CAKEPHP`), see for example **http://stackoverflow.com/questions/34067353/cakephp-3-x-continue-session-from-out-of-the-app**. – ndm May 08 '17 at 15:06
  • Thanks, I've tried as per the link (`'cookie' => 'PHPSESSID'`) however it's just giving `object(Cake\Network\Session) { [protected] _engine => null [protected] _started => null [protected] _lifetime => '120000' [protected] _isCLI => false }` even when I've logged in through `https://app.example.com`. Is some other configuration required on the *non-*Cake domain (`https://app.example.com`)? – Andy May 08 '17 at 15:36
  • @Andy A session object dump doesn't provide any details about whether it's being able to pick up a session (you'll never see the session data that way if that is what you've expected, as it's internally always being retrieved from `$_SESSION`). There should be no further configuration required on the **non**-cake domain, other than the configuration required to share the cookie with other domains in general. CakePHP uses PHPs session handler by default, and that one will be able to pick up the session just fine as long as it knows the name (and retrieves the cookie of course). – ndm May 08 '17 at 15:55