Question

According to Facebook - Authentication within a Canvas Page Document, they say that we will be getting a signed_request which consists a JSON object. Now they say that signed_request can be get through $_POST['signed_request'] I agree its working for me.

Now according to them if the user is logged in i will be getting a JSON object value like this:-

{
  "expires":UNIXTIME_WHEN_ACCESS_TOKEN_EXPIRES,
  "algorithm":"HMAC-SHA256",
  "issued_at":UNIXTIME_WHEN_REQUEST_WAS_ISSUED,
  "oauth_token":"USER_ACCESS_TOKEN",
  "user_id":"USER_ID",
  "user":{
    "country":"ISO_COUNTRY_CODE",
    "locale":"ISO_LOCALE_CODE",
    ...
  }
}

Now i want to fetch the user_id out of this so i am using this piece of code but its not working:-

if(isset($_POST['signed_request']))
{
    echo 'YES';
    $json = $_POST['signed_request'];
    $obj = json_decode($json);
    print $obj->{'user_id'};    
}

It just print the YES. Why is it so?

I have read somewhere that without app authentication i will not be able to extract the user_id but according to the facebook, this is the 1st step and authenticating the application would be 4th. I am new to it, if somebody can please help me, it will be of great help. Thanks.

Was it helpful?

Solution

I think it failed at json_decode($json) because $json is not a valid json string, as you've mentioned in comment about print_r($_POST['signed_request']);.

According to Facebook - Authentication within a Canvas Page Document, the signed_request parameter is encoded and, parsing the signed_request string will yield a JSON object.

if you're using the PHP SDK, just as Abhishek said in the comment, $facebook->getSignedRequest(); will give you the decoded json.

look here for more details on the Signed Request

OTHER TIPS

If you don't want to work with the FB SDK you can use this snippet of code to get the user_id and other variables (snippet from https://developers.facebook.com/docs/facebook-login/using-login-with-games/)

function parse_signed_request($signed_request) {
  list($encoded_sig, $payload) = explode('.', $signed_request, 2); 

  // decode the data
  $sig = base64_url_decode($encoded_sig);
  $data = json_decode(base64_url_decode($payload), true);

  // confirm the signature
  $expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
  if ($sig !== $expected_sig) {
    error_log('Bad Signed JSON signature!');
    return null;
  }

  return $data;
}

function base64_url_decode($input) {
  return base64_decode(strtr($input, '-_', '+/'));
}

Old post I know but wanted to add a reply to Art Geigel's answer (I can't comment directly on it).

Your code snippet is missing the line,

   $secret = "appsecret"; // Use your app secret here

and the complete snippet,

function parse_signed_request($signed_request) {
   list($encoded_sig, $payload) = explode('.', $signed_request, 2); 

   $secret = "appsecret"; // Use your app secret here

   // decode the data
   $sig = base64_url_decode($encoded_sig);
   $data = json_decode(base64_url_decode($payload), true);

   // confirm the signature
   $expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
   if ($sig !== $expected_sig) {
      error_log('Bad Signed JSON signature!');
      return null;
   }

   return $data;
}

function base64_url_decode($input) {
   return base64_decode(strtr($input, '-_', '+/'));
}

To answer the original question

To get data from the signed_request, include the functions above and...

$data = parse_signed_request($_POST['signed_request']);

echo '<pre>';
print_r($data);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top