0

I don't understand the code that comes after "The following PHP example demonstrates the server-side flow with CSRF protection in one self-contained example:" at http://developers.facebook.com/docs/authentication/ i.e Why is it needed? Why session_start(); is needed? I don't understand where the work with the session begins or ends. How does the CSRF protection work? Why access token is not returned right after user login?

Raj
  • 22,346
  • 14
  • 99
  • 142
Vitali Pom
  • 602
  • 1
  • 8
  • 29

1 Answers1

1

You call session_start() once at the top of your script, before anything it printed out.

After that you have access to the $_SESSION array. This allows you to store values like $_SESSION['state'] from one page call to another.

The code in the example shows a CSRF protection. The first time you call tt stores a random value in the session and compares it afterwards.

Read more about php sessions.

Update Script with comments. If you have a look at the picture above the script... I "marked" some points from there.

   // Set your facebook config here
   $app_id = "YOUR_APP_ID";
   $app_secret = "YOUR_APP_SECRET";
   $my_url = "YOUR_URL";

   // start session to store random state
   session_start();
   // get a code from the request
   $code = $_REQUEST["code"];

   // if no code was send to the script...
   if(empty($code)) {
     // generate a random, unique id and store it the session
     $_SESSION['state'] = md5(uniqid(rand(), TRUE)); //CSRF protection
     // create facebook dialog url
     $dialog_url = "https://www.facebook.com/dialog/oauth?client_id=" 
       . $app_id . "&redirect_uri=" . urlencode($my_url) . "&state="
       . $_SESSION['state'];

     // redirect user to facebook
     // Facebook login and App Permissions request
     // "GET OAuth Dialog"
     echo("<script> top.location.href='" . $dialog_url . "'</script>");
   }

   // CSRF protection: check if state parameter is the same as 
   // we stored it in the session before the redirect
   if($_REQUEST['state'] == $_SESSION['state']) {
     // do facebook auth "GET /oauth/authorize"
     $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);

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

     $user = json_decode(file_get_contents($graph_url));
     echo("Hello " . $user->name);
   }
   else {
     echo("The state does not match. You may be a victim of CSRF.");
   }
PiTheNumber
  • 22,828
  • 17
  • 107
  • 180
  • Thanks! And why access token is not returned right after user login? What does it actually do? – Vitali Pom Jan 25 '12 at 08:05
  • And what is that "facebook dialog"? – Vitali Pom Jan 25 '12 at 09:07
  • It contains the facebook login (if needed) and a app permissions request. Shown in the first two pictures on the page. – PiTheNumber Jan 25 '12 at 09:20
  • What do you not understand about it? Of course they will be mentioned in every tutorial because you need to ask the user for permissions to access his data. – PiTheNumber Jan 25 '12 at 09:43
  • I don't understand why do we check for an empty string, aren't we must be logged in to get to this step? What scenario can lead to an empty string? Another question: where did $_REQUEST's state come from - GET or POST and how did it appear there? P.S Sorry for the tons of questions. – Vitali Pom Jan 25 '12 at 10:10
  • When the user first open your page $code is empty and we generate a new state. After the redirect, facebook send this state and a code I think via GET back to the script. – PiTheNumber Jan 25 '12 at 10:27
  • Ok, I give up with this piece of code...I'll just translate it into Java when needed... Thank you! – Vitali Pom Jan 25 '12 at 10:35
  • (By the way, you meant opened the page instead of being redirected to it, right?) – Vitali Pom Jan 25 '12 at 10:43
  • Ne, I meant redirect. Have a look at the diagram with the server-side flow again. First the user loads your page. $code is not set, a new state is generated. Second you redirect to facebook with the state. Facebook then generates a code and creates another redirect back to you with the code and your state. Now you check if the state is still the same you send to facebook otherwise you have a CSRF problem. If the state is fine you call oauth/authorize and query the data the want from facebook. – PiTheNumber Jan 25 '12 at 11:01
  • Right, that's what I meant - the user is redirected to the 3rd page- not opens it and than he gets the code. – Vitali Pom Jan 25 '12 at 12:08