7

I use CakePHP 2.4. I have an OAuth signin in my website. %99.5 of signins are successfull but %0.5 fails. I have this error for months. I tried many things to debug and log but still I didn't solve the problem. Although most of the requests are good I need to solve the small part.

Scenario is like this:

  • User clicks Sign in button
  • I get request token from server (for example yahoo, twitter)
  • I save oauth_token in user's session
    for example session ID is aaa1234
  • CakePHP creates PHPSESSID cookie and save session id in this cookie.

  • I redirect user to Twitter server and user confirms my application

  • User comes to my website with oauth verifier
    a) I use user's oauth_token and oauth_verifier and get access_tokens. session ID is aaa1234. everything good.
    b) Failure. Because I can't find user's oauth_token in current session. When I check session ID, I see that ID changed, ID is now bbb2345

For the scenario b:
It seems like user has new session ID now. oauth_token can't be found in new session. But note that old session data exists in /tmp/sessions/ folder.

Session ID cookie doesn't exists for session aaa1234. But another tracking cookie that I set 2 days ago exists in cookies.

I check user agents.
It is same when user first comes and user comes back from Yahoo server.

This failure scenario happens in Chrome, Firefox, mobile browsers or other browsers, so I can't accuse browser type.
What should I check more to diagnose?

My CakePHP core.php settings:

Configure::write('Session', array(  'defaults' => 'cake'  ));
Configure::write('Session.cookie', 'MYPHPSESSID');
Configure::write('Session.timeout', 120);
Configure::write('Security.level', 'medium');

Other settings are default as mentioned in file: https://github.com/cakephp/cakephp/blob/2.5/app/Config/core.php#L182

Edit: By using this answer I checked for cookies. 20% of the erroneous users disabled cookies. I asked personally and user confirmed cookie option. But it seems like other users didn't disabled cookies. Also some of users reach my website by using Android WebViews. In WebView clients I'm sure that I don't disable cookies. Also 99% of the WebView users can successfully use website.

Community
  • 1
  • 1
trante
  • 33,518
  • 47
  • 192
  • 272
  • 1
    Well that looks like your session ID gets not passed back to the server correctly. Can happen f.e. if the session cookie is set for the first time in response to a request that redirects elsewhere straight away. – CBroe Feb 27 '14 at 21:37
  • I'm sorry I couldn't understand. If the session cookie is set for the first time then what does it do ? – trante Feb 28 '14 at 07:15
  • one question , you asked for the request token trought a dialogPopUp window or just a normal window ? – Abdou Tahiri Mar 04 '14 at 14:27
  • @AbdouTahiri not a dialog. I redirect user to Yahoo or Twitter authorization page and user leaves my website. When user authorize he comes back to my site. – trante Mar 04 '14 at 14:34
  • i mean the Yahoo login page appear in the current browser window or a separated popup window ? – Abdou Tahiri Mar 04 '14 at 14:36
  • Current browser window. – trante Mar 04 '14 at 18:17
  • I have to tell you, that you are not alone with that problem. I worked for a company, who had the same problem with a shop and a redirect to paypal and back. It was also like 1 out of 100 cases, but it was very old cakePHP (v. 1.X). Either it is a php problem, which deletes the sessions too early or something else is getting in the way. Have you tried attaching the session id as a GET parameter to your return url? Do have by any chance Plesk running on your server? – func0der Mar 07 '14 at 16:04
  • @func0der Thank you for reply. I use Cake 2.4. I have Plesk in my server but it's not possible to pass session ID inside the return URL. Also I don't prefer such a solution. I would prefer to find cause :) – trante Mar 07 '14 at 18:13
  • Are any of these tokens comprised of characters which could have a special meaning? Something that needs to be escaped or somehow is misinterpreted somewhere in your code? Could explain the seeming randomness. Sounds like the code needs more checks / logging. – ficuscr Mar 08 '14 at 07:30
  • @ficuscr tokens can't have special characters because I don't create them. they are created by API server. In case there exists a fault that can create bad tokens, that would make tokens to be written to session wrongly, or tokens can't be written to session. But the problem is, when user come backs, there exists no cookie that holds session id. But there exists a file inside my temp folder with the old session ID. but when user comes back he now has new session ID, because of coookie doesn't exists. – trante Mar 08 '14 at 11:12
  • @trante - have a look at my answer. I believe it can be due to his session created on HTTP and he comes back on HTTPS or the other way around. – Shay Elkayam Mar 08 '14 at 18:56
  • @trante Maybe Plesk is the problem here. I mean not plesk in general, but the configuration it provides for apache and php. Maybe there is somehow something wrong. You could just provide the return url like this: http://returnhere.com/?MYPHPSESSID=XXXXXXXXX I know, that this is bad practice, but you can try if this solves your problem and you only have to use it in your return url. If it does solve the problem, I think, that the cause is somewhere in your server configuration. – func0der Mar 09 '14 at 19:47

5 Answers5

9

Your session id might be lost because of a redirect between schemes. In case your user received a session id on HTTP and then came back on HTTPS (or vice-versa) his session would be lost/replaced by an old session he had previously on that scheme.

This is not 100% certain, but if I were you, I'd try to give it a look (it happened to me also in a past project).

EDIT
Explanation:

The clients obtain their session on HTTP, they are redirected for oauth purposes, and when they come back, they come via HTTPS.

PHP Normal sessions ($_SESSION) are lost when moving between HTTP and HTTPS. The session itself is kept on server side, but the client loses the session_id, thus the server doesn't recognize him and the session is lost, so I you were using pure PHP, 100% of your clients were to lose session on their way back.

CakePHP handles this common problem via cookies that save the sesion id, and then when the client comes back without session_id on the request headers, its session is restored because of the cookie. The 0.05% of your clients that fails, are clients with one (or more) of the following:

  1. Cookies disabled (more common)
  2. Browsers that don't retain cookies from the same website when switching between HTTP/HTTPS (much more rare)

Possible solutions:

  1. initialize the cookie on HTTPS to begin with (i.e first check if the user is on HTTP, then redirect him to HTTPS, then init the session, then redirect him to oauth endpoint) - I personally recommend it.

  2. some oauth providers take parameters for the url to redirect the user when he finishes his authentication. You can use this and send its session id as a parameter. - I don't recommend this, because then you might expose your client's session id to attackers.

Good luck!

Shay Elkayam
  • 4,128
  • 1
  • 22
  • 19
  • I use HTTP on my site. I redirect user to HTTPS server. Then HTTPS server redirects to my HTTP website. I had set cookie in my HTTP site. If it was a problem wouldn't I have this problem in each request ? I get this problem nearly in %0.5 of requests. – trante Mar 08 '14 at 21:02
  • Cakephp uses cookies to keep the session between http and https. The 0.05 percent are browsers with cookies disabled and/or browser that don't support usage of the same cookie across http and https. – Shay Elkayam Mar 09 '14 at 07:24
  • @trante, read my updated answer. I think it has the information you need. – Shay Elkayam Mar 09 '14 at 07:46
  • I'm pretty sure that even cookie-enabled browsers had this issue. I don't have a chance to use HTTPS scheme in my server. I will dig more to find out whether the scheme causes problem. – trante Mar 09 '14 at 18:39
  • If he has only HTTP running on his web server, the return url transmitted to OAuth could not be HTTPS. So even though this is a pretty good piece of advice, I do not think it applies here, does it? – func0der Mar 09 '14 at 19:51
1

I'd imagine that CBroe is on the money here. I've run into this before as well (not specifically with OAuth, but with other redirects that set a session cookie).

More info here: Losing session variables after redirect

Community
  • 1
  • 1
Ben Hitchcock
  • 1,368
  • 10
  • 12
  • I redirect user to API server with CakePHP's redirect function. It runs an exit() automatically: https://github.com/cakephp/cakephp/blob/2.5/lib/Cake/Controller/Controller.php#L756 – trante Feb 28 '14 at 07:13
  • I have compiled a list of things to check...I don't know if it is relevant to your case...http://stackoverflow.com/questions/17242346/php-session-lost-after-redirect – dayuloli Feb 28 '14 at 08:50
  • @dayuloli Strange thing is, this happens very rarely. Most of the signins ends with success. – trante Mar 01 '14 at 16:47
  • @trante Since I had really big issues with CakePHP and failing AJAX requests, because of a missing "exit();", you should definitely give it a try. – func0der Mar 07 '14 at 16:18
0

Why don't you check session ID is isset or not while in the case when it comes unset or we can say comes different from the server ? and another way is, if we set our session variable in one temporary var, so while that comes blank then this would append to our session variable.

SagarPPanchal
  • 9,839
  • 6
  • 34
  • 62
  • When user returns back to my website session ID is regenerated by CakePHP. In case of old session destroy, I can't know what the old session ID was. Old session ID's cookie doesn't exists. – trante Mar 08 '14 at 08:59
  • Even I set session ID to temporary variable, when user comes back my application doesn't know the old session ID because cookie doesn't exists. And temporary variable is inside another session that can't be known by user. – trante Mar 08 '14 at 14:10
0

What i have found is that after redirect the url changes 127.0.0.1:8000 to localhost:8000, due to this session is lost. Test it altering localhost:8000 to 127.0.0.1:8000, you will get the session.

-4

Write this at the very beginning of all your controllers:

!session_id() ? session_start() : '';

I'm not sure why but I've faced the same problem myself. I've found that the session id gets lost somehow when OAuth redirect is used in CakePHP. The above line ensures that a session id always exists. Hope this helps.

Muntasir
  • 101
  • 10
  • You obviously never worked with CakePHP Sessions. You never use `session_start()` in your Controllers anywhere. – Oldskool Mar 06 '14 at 20:40
  • @Muntasir CakePHP has its own session handlers which work a little different from the PHP build-in sessions. – func0der Mar 07 '14 at 16:06