Facebook服务器端身份验证返回短暂的access_token


Facebook server-side authentication returns short-living access_token

我已经在Facebook开发者小组中发布了这个问题,但没有人能给出一个有竞争力的答案。我有一个使用服务器端身份验证的Facebook应用程序。代码看起来像这样:

$config = array();
  $config['appId'] = $fbconfig['appid'];
  $config['secret'] = $fbconfig['secret'];
  $config['fileUpload'] = false; // optional
  $facebook = new Facebook($config);

    //Facebook Authentication part
    $mobile = false;
    $code = false;
    if (isset($_GET["code"]) && !empty($_GET["code"]) && strlen($_GET["code"])>1){
    $code  = trim($_GET["code"]);

    }
    //MOB VAR
if (isset($_REQUEST['mob']) && !empty($_REQUEST['mob']))
    {
    mobile = true; 
    }else{
         }

    if ($mobile){
 $loginUrl = $facebook->getLoginUrl(
     array(
     'redirect_uri' => $fbconfig['baseUrl'].$loginpart,
     'scope'  => 'email,user_likes'
          )
                                    );
 $token_url = "https://graph.facebook.com/oauth/access_token?client_id=".APP_ID."&redirect_uri=".urlencode($fbconfig['baseUrl'].$loginpart)."&client_secret=".$fbconfig['secret']."&code=".$code;
}else{

 $loginUrl = $facebook->getLoginUrl(
            array(
            'redirect_uri' => $fbconfig['appBaseUrl'].$loginpart,
            'scope'  => 'email,user_likes'
                 )
                                    );
$token_url = "https://graph.facebook.com/oauth/access_token?client_id=".APP_ID."&redirect_uri=".urlencode($fbconfig['appBaseUrl'].$loginpart)."&client_secret=".$fbconfig['secret']."&code=".$code;
}


if ((!isset($_GET['code']) || empty($_GET['code']) ) ) {
        echo "<script type='text/javascript'>top.location.href = '$loginUrl';</script>";
        exit;
    } else{
   if ($code){
    $response  =  file_get_contents($token_url);
    $params  = null;
    parse_str($response, $params);
    $access_token = $sessionKey = $AccessToken = $params['access_token'];
    if(isset($AccessToken) && !empty($AccessToken)){
    if(isset($params['expires'])){
      $ExpDate = $params['expires'];

我缩短代码是为了不惹恼你。


由于某种原因,代码返回短$ExpDate,可以从3000秒到7000秒。并非所有用户都会出现这种情况,但有10%-15%的用户会出现这种情况。

What I have try

  • 尽管Facebook应该返回长期有效的access_token I试图用/oauth/access_token? url交换它。没有结果:返回相同的过期时间。
  • 我试着抓住$SERVER['HTTP_USER_AGENT']来找出什么用户使用短期access_token的常见问题。没有结果:一切都是不同的(它们可以来自移动设备,桌面,IOS原生Facebook应用....)
  • 我改变了我的设置从隐私设置到每一个可能的版本,安装,删除应用程序多次试图重现的情况。没有结果:对我来说它工作得很好。
  • 我保存了用户的代码,并尝试手动获取access_token。我没能做到这一点,因为我忘记了密码只能使用一次。

How can You Guys Help

  • 如果有人有相同的认证方法,请检查您的数据库。你有同样的问题吗?
  • 如果有人有一个想法,为什么会发生这种情况,请帮助找到原因。如果我们发现这是一个bug,我们可以在Facebook上创建一个bug报告

谢谢。

你看到的行为是正确的。

您当前正在将代码交换为短期访问令牌-这是必需的。由于Facebook删除了offline_access权限,因此获得寿命较长的访问令牌的唯一方法是将寿命较短的访问令牌交换为寿命较长的访问令牌。

请参阅关于移除offline_access(特别是与OAuth相关的场景4)的文章。在这里,他们引入了长期访问令牌的概念,并告诉您如何获得一个。

实现这一目标的简单方法是使用您的短时间访问令牌-例如AQADEADBEEF并获取此…

https://graph.facebook.com/oauth/access_token?grant_type=fb_exchange_token&client_id={client_id}&client_secret={client_secret}&fb_exchange_token=AQADEADBEEF

注意4个参数grant_type、client_id、client_secret和fb_exchange_token。URL与您获得原始访问令牌时的URL相同,但参数略有不同。适当插入client_idclient_secret

你会得到一个访问令牌与一个更长的到期时间- 90天我相信。Facebook对任何访问令牌的长度都相当模糊。只有当你拿到它的时候,你才知道它的有效期。长期访问令牌仍然会过期,Facebook目前没有办法更新它。