Facebook应用程序:OAuthException:必须使用活动访问令牌

时间:2011-12-31 09:54:14

标签: facebook sdk

我有下一个问题将我的旧Facebook应用程序迁移到Oauth 2.0:

当我尝试读取用户配置文件时(在php代码中)我收到错误:“ OAuthException:必须使用活动访问令牌来查询有关当前用户的信息。

应用程序通过javascript进行登录操作,然后重定向到一个页面,从php获取用户配置文件。

javascript代码:

<script type="text/javascript">
window.fbAsyncInit = function() {   
    FB.init({
        appId   : '<?php echo $facebook->getAppId() ?>',
        cookie  : true, // enable cookies to allow the server to access the session
        xfbml   : true, // parse XFBML
        oauth : true    // enable oauth
    });

    // whenever the user logs in, we refresh the page
    FB.Event.subscribe('auth.login', function(response) {
        window.location="index.php";
    });

};

(function() {
    var e = document.createElement('script');
    e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
    e.async = true;
    document.getElementById('fb-root').appendChild(e);
}());


function login () {
 FB.login(function(response) {
   if (response.authResponse) {
     //console.log('Welcome!  Fetching your information.... ');
     FB.api('/me', function(response) {
       //alert('Good to see you, ' + response.name + '.');
       var url="./code.php";
       window.location=url;
     });
   } else {
     alert("Debes de identificarte y aceptar las condiciones para obtener el descuento");
   }
 }, {scope: 'email'});

};


</script>

php部分(在code.php中):

require 'facebook-php-sdk/src/facebook.php';

// Create our Application instance (replace this with your appId and secret).
$facebook = new Facebook(array(
  'appId'  => 'xxxxxxxxxxxxxxxxx',
  'secret' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
));
$user = $facebook->getUser();   
if ($user) {
    try {
        // Proceed knowing you have a logged in user who's authenticated.
        $me = $facebook->api('/me');
.....

我已经阅读了不同的帖子,尝试过从javascript登录响应或cookie中获取access_token,然后调用api('me /?access_token = ...),但它无效。

编辑:非常感谢大家,现在正在工作!!

由于

4 个答案:

答案 0 :(得分:1)

@moguzalp @brandwaffle @ yauros,在非画布应用程序上获取signed_request。我使用了以下代码,它适用于我。 如果您使用的是Oauth 2.0,那么您将获得名为fbsr_app_id的cookie。这个cookie只不过是signed_request。

您可以获取此cookie并解析signed_request以获取用户ID和access_token,如下所示:

$cookieName = 'fbsr_' . $app_id;

function parse_signed_request($signed_request, $secret) {
  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);

  if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
    error_log('Unknown algorithm. Expected HMAC-SHA256');
    return null;
  }

  // check sig
  $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, '-_', '+/'));
}
$fbsr=parse_signed_request($_COOKIE[$cookieName],$application_secret);

$user_id=$fbsr['user_id'];

答案 1 :(得分:0)

@MehulHingu建议解决方案适合您的情况

但是,您可以使用以下方法做得更好:在您的PHP代码中,获取&amp;解析signed_request并解压缩access_token(如果用户已经通过您的Facebook验证您的应用并给予相关权限)php php api < / p>

当您的画布调用时,您将获得signed_requesthttps://app.faceobook.com/yourapp

否则,使用javascript登录,您可以轻松注册并获得许可。

当您的注册用户来时,此方法会更有效。

注意:正如brandwaffle所说,如果您的应用是画布应用

,此建议有效

答案 2 :(得分:0)

如果您使用的是java脚本FB.Login函数,那么您将获得一个访问令牌和用户ID作为响应

var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;

你可以通过Ajax将accessToken和用户id传递给你的php代码,并在php中的api调用中使用它。

请记住,如果您使用java脚本FB.login登录,那么

$user = $facebook->getUser();

无法在php中使用。

因此要检查用户是否已登录并使用以下代码进行自动验证

    try {
    $me_arr = array(
    'access_token'=>$access_token ,    
    );
        $user_profile = $fb->api('/me',$me_arr);
        if($user_profile){
    // user is authanticated

                        }
    else
    {
    // not 

    }

      } catch (FacebookApiException $e) {

        error_log($e);

}

答案 3 :(得分:0)

更新:您的JS代码在重新加载页面之前就将您注销。这将在PHP方面弄乱大片! :)

只要用户已登录并通过JavaScript SDK批准了您的应用,您就应该只需要在PHP端获取访问令牌以使一切正常。我修改了你的例子如下:

require 'facebook-php-sdk/src/facebook.php';

// Create our Application instance (replace this with your appId and secret).
$facebook = new Facebook(array(
  'appId'  => 'xxxxxxxxxxxxxxxxx',
  'secret' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
));
$user = $facebook->getUser();   
$token = $facebook->getAccessToken();
if ($user) {
  try {
    // Proceed knowing you have a logged in user who's authenticated.
    $me = $facebook->api('/me' . $token);

我知道您之前提到尝试此示例,因此值得知道,当您仍然登录Facebook时,您的访问令牌可能无效。这将导致传递if($ user)检查,但尝试使用无效的access_token进行API调用。为了确保不会发生这种情况,var_dump out $ token值 - 如果你的app_id和秘密用'|'分隔,那么你就没有有效的访问令牌。

我能够在测试应用程序中登录JS端,然后在PHP端加载代码并让它显示我的用户名。你可以在这里看到它:http://brandwaffle.info/facebook/