Facebook 访问令牌 - 服务器端身份验证

Facebook 访问令牌 - 服务器端身份验证

问题描述:

您好,我正在尝试使用 Facebook 服务器端身份验证来获取访问令牌,但不断向我抛出错误.

Hello i'm trying to use facebook server-side authenticaion to get the access token but keep getting errors thrown at me.

我正在使用波纹管:

$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) . "&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);
   }
   else {
     echo("The state does not match. You may be a victim of CSRF.");
   }

App ID 和 APP Secret 已被删除,所以不要担心那部分.我收到有关 get_file_contents 超时的错误.

App ID and APP Secret have been removed so dont worry about that part. I get errors about the get_file_contents time out.

[function.file-get-contents]:无法打开流:连接定时出来

[function.file-get-contents]: failed to open stream: Connection timed out

是否有其他或更好的方法来获取访问令牌?

Is there another or better way of getting the access tokens?

Bellow 是我尝试过的包含 cURL 想法的版本:

Bellow is the version i have tried including the cURL idea:

function get_data_cURL($url)
{
  $ch = curl_init();
  $timeout = 5;
  curl_setopt($ch,CURLOPT_URL,$url);
  curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
  curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout);
  $data = curl_exec($ch);
  curl_close($ch);
  return $data;
}

function getAccessToken(){
    $app_id = FB_APP_ID;
    $app_secret = FB_SECRET_ID;
    $canvas_URL = FB_CANVAS_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($canvas_URL) . "&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($canvas_URL)
        . "&client_secret=" . $app_secret . "&code=" . $code;

     $returned_content = get_data_cURL($token_url);
    echo'Well Done! - '.$returned_content;

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

详情:

应用设置 - 画布 URL:http://www.apps.elistone.co.uk/DrawMyFriend/

App Settings - Canvas URL: http://www.apps.elistone.co.uk/DrawMyFriend/

FB_APP_ID = The Facebook App ID
FB_SECRET_ID = The Facebook Secret ID
FB_CANVAS_URL = http://www.apps.elistone.co.uk/DrawMyFriend/

即使有了这个更新,我仍然收到这个错误:

Even with this update i still get this error:

旧错误

干得好!- {"error":{"message":"验证验证时出错code.","type":"OAuthException","code":100}}

Well Done! - {"error":{"message":"Error validating verification code.","type":"OAuthException","code":100}}

新错误

这似乎是由于重定向删除了状态代码引起的.

This seems to be caused by the redirect removing the state code.

状态不匹配.您可能是 CSRF 的受害者.——193c791ddd71c3fd84d411db5554c315(州代码)

The state does not match. You may be a victim of CSRF. - 193c791ddd71c3fd84d411db5554c315 (state code)

我还尝试通过更改来绕过 CSRF 保护:

I have also tried bypassing the CSRF protection by changing:

if($_REQUEST['state'] == $_SESSION['state'])

致:

 if(!empty($code))

但这仍然会出现旧的错误问题,我听说这是由重定向链接中的某些内容引起的,但我不知道如何解决.

But this still gives the old error problem, I have heard it is caused by something in the redirect link but im not sure how to fix it.

问题已解决

经过一段时间的尝试,我使用 PHP SDK 获取用户访问令牌:

After trying along time i have resulted to using the PHP SDK using the below to get the user access token:

$app_id = FB_APP_ID;
$app_secret = FB_SECRET_ID;
$canvas_URL = FB_PAGE_URL;
$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=" . $canvas_URL . "&state="
    . $_SESSION['state'];

  echo("<script> top.location.href='" . $dialog_url . "'</script>");
}
if($_REQUEST['state'] == $_SESSION['state']) {
$facebook->api('oauth/access_token', array(
    'client_id'     => FB_APP_ID,
    'client_secret' => FB_SECRET_ID,
    'type'          => 'client_cred',
    'code'          => $code,
));
$token = $facebook->getAccessToken();
echo$token;
}

我现在要把它变成某种功能.非常感谢大家的时间和帮助.

I am now going to turn this into some sorta function. Thank you very much for everyones time and help.

希望这能帮助到未来有需要的人(除非 Facebook 突然改变了一切)

Hope this helps people in need in the future (unless Facebook changes everything suddenly)

我推荐你使用 用于与 Facebook API 通信的 PHP SDK 库.只需使用 getAccessToken()getAccessTokenFromCode() 方法.

I recommend you to use PHP SDK library for communicating with Facebook API. And simply use getAccessToken() or getAccessTokenFromCode() methods.

更新

要检索用户访问令牌,您必须在获取访问令牌之前发送 oauth 请求.答案更新中的详细信息:

To retrieve user access token you have to send oauth request before getting access token. Details in answer update:

    $facebook->api('oauth/access_token', array(
        'client_id'     => APP_ID,
        'client_secret' => APP_SECRET,
        'type'          => 'client_cred',
        'code'          => $code,
    ));
    $token = $facebook->getAccessToken();