Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Losing session after a redirect to another domain then back

I am creating a login system where I use a persons email address as a unique identifier in my DB. People can login using any openid provider such as google ect (also facebook), It will simply take the email and store that as a unique identifier in the users table in my sql DB. (means I dont have to worry about email verification, passwords ect and users dont have to register).

This works, by opening up a new window using a link/javascript, my php script is then directed to google or whoever the provider is. Then they enter there details, then google/ect will automaticly redirect the window back to my login script along with (if it worked) the user details (most importantly the email).

Now on the response I look at the email, look if its in my database, if not add it, if so, using $_SESSION, log a user into my site.

I have this working perfectly using the openid mechanism (google, yahoo, ect). I am trying to get it working with facebook also and having great difficulty. It is able to log a user into fb, grab a users email ect. However as soon as I try to log a user into my site, it does not work. For some reason it has a seperate session(inc seperate sessionid) for the new window I have opened (and my script + redirection runs in), then to the rest of my site?

Just wondering if anyone has any idea why this would be happening.

This is what the login script looks like (thats runs in the new window):

<?php 

   $app_id = "YOUR_APP_ID";
   $app_secret = "YOUR_APP_SECRET";
   $my_url = "YOUR_URL";

   session_start();
   $code = $_REQUEST["code"];

   if(empty($code)) {
     $_SESSION['state'] = md5(uniqid(rand(), TRUE)); //CSRF protection
     $dialog_url = "https://www.facebook.com/dialog/oauth?client_id=" 
       . $app_id . "&redirect_uri=" . urlencode($my_url) . "&scope=email&state="
       . $_SESSION['state'];

     echo("<script> top.location.href='" . $dialog_url . "'</script>");
   }

   if($_REQUEST['state'] == $_SESSION['state']) {
     $token_url = "https://graph.facebook.com/oauth/access_token?"
       . "client_id=" . $app_id . "&redirect_uri=" . urlencode($my_url)
       . "&client_secret=" . $app_secret . "&code=" . $code;

     $response = file_get_contents($token_url);
     $params = null;
     parse_str($response, $params);

     $graph_url = "https://graph.facebook.com/me?access_token=" 
       . $params['access_token'];

     $user = json_decode(file_get_contents($graph_url));
     echo("Hello " . $user->name);

     // try_register_or_login($user->email);

   }
   else {
     echo("The state does not match. You may be a victim of CSRF.");
   }

 ?>

source: https://developers.facebook.com/docs/authentication/

I have spent far to many hours trying to work this out myself. Any help would be much appreciated.

like image 302
Josh Mc Avatar asked Feb 23 '23 13:02

Josh Mc


2 Answers

In case anyone is experiencing this and don't know why or how to solve it:

I was having the same issue. My page redirected to another site, user do some stuff there and this site redirects him back to my site, and the session was lost in this step. The problem was with my cookies setup.

I was having the following apache directive:

Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure;SameSite=Strict

And the problem was specifically with SameSite=Strict mode, as Strict value withheld the cookie from any cross-site usage.

Setting the value to Lax:

Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure;SameSite=Lax

Solved the issue without compromising security, as Lax mode allow some GET cross-site request, as long as is a top level request.

Top level request occurs whenever the URL in the address bar changes because of this navigation. This is not the case for iframes, images or XMLHttpRequests.

Reference: Preventing CSRF with samesite cookie attribute

like image 101
mdmg Avatar answered Feb 26 '23 04:02

mdmg


I believe the issue may have to do with crossing domains or potentially how the cookie is set.

For crossing domains, take a look at Cross domain cookies

Another possibility is the flags that are set with the cookie. I had this exact issue when I set the secure flag on a cookie and then tried to access it via a non secure (http) page. Also, if the httponly flag is set, it will cause problems for javascript. You can read about both flags at http://www.php.net/manual/en/function.setcookie.php

like image 36
Marty Avatar answered Feb 26 '23 03:02

Marty