为啥 Facebook PHP SDK getUser 总是返回 0?

Posted

技术标签:

【中文标题】为啥 Facebook PHP SDK getUser 总是返回 0?【英文标题】:Why is Facebook PHP SDK getUser always returning 0?为什么 Facebook PHP SDK getUser 总是返回 0? 【发布时间】:2011-10-11 00:59:55 【问题描述】:

我正在尝试使用需要来自 Facebook 用户的一些信息的网站,我正在使用 php 和 JS SDK。

我在 PHP 中有一个函数:

public function isLoggedOnFacebook() 
    $user = $this->_facebook->getUser();
    if ($user) 
        return $this->_facebook->api("/$user");
    
    return false;

在一个类上,该类在 $this->_facebook 中持有来自 SDK 的 facebook 对象。

然后在一个块上我这样做:

<?php if (!$this->isLoggedOnFacebook()): ?>
<div>
   <fb:login-button show-faces="true" perms="email"  />
</div>
<?php endif ?>

FB JS 环境设置正确(我认为),所以它可以工作。所以用户得到弹出窗口并授权该站点。

问题是即使app被用户授权后$user总是0,意思是$facebook-&gt;getUser()总是返回0,然后列出用户的面孔,包括登录的用户,但是如果我让它调用@ 987654326@ 之类的,就会抛出无效令牌异常。

我已经看到了这个问题,但我没有看到解决方案,我不知道 问题出在哪里,我的想法已经用完了。

在应用程序部分的开发人员 Facebook 页面上有一个网站选项卡,您可以在其中设置您的站点 URL 和站点域,我认为这是我的问题的原因,但我不知道正是这些字段应该包含的内容。

【问题讨论】:

回答我自己的问题,我发现当前的JS SDK与PHP SDK 3.0.0不兼容。应该很快就会有新的JS SDK发布了,但是还没有上线,所以这就是它不起作用的原因。 看看这个:How to properly handle session and access token with Facebook PHP SDK 3.0?. 我也遇到了 3.0.1 PHP API 的 getUser() == 0 问题! @fd8s0 你打算在这里选择答案吗? 嗯,所有答案都有相关信息,正如我在之前的评论中所说,这个特殊问题是由于一段时间(现在已经消失)facebook提供的SDK相互不兼容而引起的.现在为了将来参考,我选择了一篇不错的博客文章,因为我认为它的工作原理非常清楚。 【参考方案1】:

我遇到了同样的问题,我发现这是因为 SDK 使用了变量 $_REQUEST,而在我的环境中与 $_GET$_POST$_COOKIE 变量合并的情况并非如此。

我认为这取决于 PHP 版本,这就是为什么有人通过启用 cookie 使其工作的原因。

我在 base_facebook.php 中找到了这段代码:

protected function getCode() 
    if (isset($_REQUEST['code'])) 
        if ($this->state !== null &&
                isset($_REQUEST['state']) &&
                $this->state === $_REQUEST['state']) 

            // CSRF state has done its job, so clear it
            $this->state = null;
            $this->clearPersistentData('state');
            return $_REQUEST['code'];
         else 
            self::errorLog('CSRF state token does not match one provided.');
            return false;
        
    

    return false;

我通过创建 $server_info 变量对其进行了修改,如下所示。

protected function getCode() 
    $server_info = array_merge($_GET, $_POST, $_COOKIE);

    if (isset($server_info['code'])) 
        if ($this->state !== null &&
                isset($server_info['state']) &&
                $this->state === $server_info['state']) 

            // CSRF state has done its job, so clear it
            $this->state = null;
            $this->clearPersistentData('state');
            return $server_info['code'];
         else 
            self::errorLog('CSRF state token does not match one provided.');
            return false;
        
    

    return false;

【讨论】:

这对我也有用。讨厌改变图书馆,但它有效。如果这对任何人有帮助的话,这是在一个 codeigniter 安装上。 天哪,这解决了 getUser() === 0 问题。还有codeigniter。 谢谢!!我浪费了大约一天的时间来调试它。最终在我的控制器的构造函数中重新创建了超全局数组:function __construct() parent::__construct(); $_REQUEST = array_merge($_GET, $_POST, $_COOKIE); 这个修复也适用于我,在 Code igniter 安装上。这可能是 CI 独有的...... @alexg,您不必编辑库。只需在使用库之前执行$_REQUEST = array_merge($_GET, $_POST, $_COOKIE);【参考方案2】:

我遇到了类似的问题。 $facebook->getUser() 返回 0,有时它在用户未实际登录时返回有效的用户 ID,当我尝试进行图形 api 调用时导致致命的 Oauth 错误。我终于解决了这个问题。我不知道这是否是正确的方法,但它有效。这是代码:

<?php
include 'includes/php/facebook.php';
$app_id = "APP_ID";
$app_secret = "SECRET_KEY";
$facebook = new Facebook(array(
    'appId' => $app_id,
    'secret' => $app_secret,
    'cookie' => true
));

$user = $facebook->getUser();

if ($user <> '0' && $user <> '')  /*if valid user id i.e. neither 0 nor blank nor null*/
try 
// Proceed knowing you have a logged in user who's authenticated.
$user_profile = $facebook->api('/me');
 catch (FacebookApiException $e)  /*sometimes it shows user id even if user in not logged in and it results in Oauth exception. In this case we will set it back to 0.*/
error_log($e);
$user = '0';


if ($user <> '0' && $user <> '')  /*So now we will have a valid user id with a valid oauth access token and so the code will work fine.*/
echo "UserId : " . $user;

$params = array( 'next' => 'http://www.anujkumar.com' );
echo "<p><a href='". $facebook->getLogoutUrl($params) . "'>Logout</a>";

$user_profile = $facebook->api('/me');
echo "<p>Name : " . $user_profile['name'];
echo "<p>";
print_r($user_profile);

 else /*If user id isn't present just redirect it to login url*/
header("Location:$facebook->getLoginUrl(array('req_perms' => 'email,offline_access'))");


?>

【讨论】:

您好 Anuj,感谢您提供代码。有一个问题,但每当我第一次成功登录时,第二次它就不起作用,它显示 500 Error Internal server error。有什么想法吗?【参考方案3】:

查看这篇博文:http://thinkdiff.net/facebook/new-javascript-sdk-oauth-2-0-based-fbconnect-tutorial/

新的JS SDK已经发布-https://developers.facebook.com/blog/post/525

【讨论】:

请在这里总结一下博文?如果链接失效,我们将一无所有。 我理解 Todds 的意见,我接受了这个答案,因为博客是最完整的信息,它只是一个教程,现在它实际上与 2011 年不同。我的问题(我是问了这个问题)是由冲突的 js 和 php sdks 版本引起的。这个问题似乎是由各种各样的问题引起的,这就是为什么很多答案都适用,我认为彻底查看所有细节是一个合适的答案。【参考方案4】:

您需要确保您的应用设置为从查询字符串而不是 uri_fragment 中获取代码参数,这可以在 facebook 应用页面apps&gt;settings&gt;permissions 上设置。

使用$facebook-&gt;getLoginUrl() 为我提供了登录 URL。

【讨论】:

【参考方案5】:

检查您的配置数组。 确保在设置值时使用正确的字符串加引号。

$config = array();
$config["appId"] = $APP_ID;
$config["secret"] = $APP_SECRET;
$config["fileUpload"] = false; // optional

这行得通。

$config = array();
$config[‘appId’] = 'YOUR_APP_ID';
$config[‘secret’] = 'YOUR_APP_SECRET';
$config[‘fileUpload’] = false; // optional

这是来自http://developers.facebook.com/docs/reference/php/ 网站的直接复制/粘贴,由于奇怪的曲折引号而无法使用。

长答案是,您“检查”应用程序签名的哈希值没有得到正确检查,因为应用程序密钥没有返回有效值(实际上它什么也没返回)......所以hash_hmac 函数返回一个不正确的值,等等......

【讨论】:

刚刚救了我的命,我太愚蠢了,他们确实引用了错误的引号,我复制/粘贴了它!【参考方案6】:

在通过 base_facebook.php 调试后我发现,因为不知何故我丢失了我的 .crt 文件,所以访问令牌永远无效。确保你有你的 fb_ca_chain_bundle.crt 在:https://github.com/facebook/facebook-php-sdk/blob/master/src/fb_ca_chain_bundle.crt

【讨论】:

这个工作!!!!非常感谢!!!!!最后(三天)一些线索!只需确保您在同一目录中有 base_facebook.php、facebook.php 和 fa_ca_chain_bundle.crt。检查以 /** * 版权所有 2011 Facebook, Inc. * 开头的 .php 文件和带有 ## ## ca-bundle.crt 的 .crt -- CA 根证书捆绑包 ## ## 来自 Mozilla 的证书数据: 2012 年 10 月 18 日星期四 19:05:59【参考方案7】:

几小时又一小时付诸东流。 Stack Overflow 或其他网站上关于此的帖子都没有为我的问题提供解决方案。我终于进入了库代码,并弄清楚了它到底死在了哪里。

在我的使用 XAMPP for Windows 的开发机器上,我不断获得 0 来登录,而我的测试服务器可以正常工作。在意识到异常被抛出但被隐藏后,我在 base_facebook.php 中添加了一个 $e->getMessage(),它指出我遇到了 SSL 错误。以下帖子 HTTPS and SSL3_GET_SERVER_CERTIFICATE:certificate verify failed, CA is OK 引导我找到了解决方案。

解决办法:

在 base_facebook.php 中,在 curl_exec($ch) 之前添加以下内容:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

您可能应该将以上内容包装在您用来确定您是否处于开发模式的任何标志中,因为您不希望在生产系统中使用上述行。例如:

if ( getenv( 'environment' ) === 'development' ) 
    curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );

【讨论】:

【参考方案8】:

查了很久,终于找到原因了。

请在设置-->高级-->迁移-->弃用离线访问中登录开发者应用程序-->禁用

你会发现 $facebook->getUser() 会起作用。

另一件事。新建 facebook 类时最好添加域;

$facebook = new Facebook(array(
'appId' => APP_ID,//$app_id,
'secret' => APP_SECRET,//$app_secret,
'cookie' => true,
'domain'=>'xxxdomain.com',
));
$session = $facebook->getUser();    

【讨论】:

【参考方案9】:

在你的代码中试试这个: 如果条件为真,您将被重新定向到 facebook,然后自己登录,我希望您到时候一切顺利,但请记住使用新的 php SDK 库

if(($facebook->getUser())==0)

 header("Location:$facebook->getLoginUrl(array('scope' => 'photo_upload,user_status,publish_stream,user_photos,manage_pages'))");
 exit;

else 
$accounts_list = $facebook->api('/me/accounts');
echo "i am connected";

【讨论】:

【参考方案10】:

我解决了这个问题,因为我遇到了同样的问题。 只需转到 developers.facebook.com/apps 然后导航到您的应用 点击 EDIT APP 按钮

如果您已选中“Facebook 上的应用”并输入了一个画布 URL 该应用程序无法在 facebook 之外运行 将在 apps.facebook.com/ 下工作

只需删除这个对我有用的检查

【讨论】:

【参考方案11】:
<?php

require 'facebook.php';

// Create our application instance
// (replace this with your appId and secret).
$facebook = new Facebook(array(
  'appId'  => 'YOUR_APP_ID',
  'secret' => 'YOUR_APP_SECRET',
));

// Get User ID
$user = $facebook->getUser();

// We may or may not have this data based 
// on whether the user is logged in.
// If we have a $user id here, it means we know 
// the user is logged into
// Facebook, but we don’t know if the access token is valid. An access
// token is invalid if the user logged out of Facebook.

if ($user) 
  try 
    // Proceed knowing you have a logged in user who's authenticated.
    $user_profile = $facebook->api('/me');
   catch (FacebookApiException $e) 
    error_log($e);
    $user = null;
  


// Login or logout url will be needed depending on current user state.
if ($user) 
  $logoutUrl = $facebook->getLogoutUrl();
 else 
  $loginUrl = $facebook->getLoginUrl();


// This call will always work since we are fetching public data.
$naitik = $facebook->api('/naitik');

?>
<!doctype html>
<html xmlns:fb="http://www.facebook.com/2008/fbml">
  <head>
    <title>php-sdk</title>
    <style>
      body 
        font-family: 'Lucida Grande', Verdana, Arial, sans-serif;
      
      h1 a 
        text-decoration: none;
        color: #3b5998;
      
      h1 a:hover 
        text-decoration: underline;
      
    </style>
  </head>
  <body>
    <h1>php-sdk</h1>

    <?php if ($user): ?>
      <a href="<?php echo $logoutUrl; ?>">Logout</a>
    <?php else: ?>
      <div>
        Login using OAuth 2.0 handled by the PHP SDK:
        <a href="<?php echo $loginUrl; ?>">Login with Facebook</a>
      </div>
    <?php endif ?>

    <h3>PHP Session</h3>
    <pre><?php print_r($_SESSION); ?></pre>

    <?php if ($user): ?>
      <h3>You</h3>
      <img src="https://graph.facebook.com/<?php echo $user; ?>/picture">

      <h3>Your User Object (/me)</h3>
      <pre><?php print_r($user_profile); ?></pre>
    <?php else: ?>
      <strong><em>You are not Connected.</em></strong>
    <?php endif ?>

    <h3>Public profile of Naitik</h3>
    <img src="https://graph.facebook.com/naitik/picture">
    <?php echo $naitik['name']; ?>
  </body>
</html>

【讨论】:

【参考方案12】:

$facebook-&gt;getUser() 将返回 0,如果用户未对应用进行身份验证。

使用 $facebook-&gt;getLoginUrl 获取 URL 以对应用进行身份验证。

【讨论】:

【参考方案13】:

我在我的 Facebook 应用程序上遇到了完全相同的问题,经过 2 天的头发拉伤后,我终于弄明白了。原来是getLoginUrl() 中的redirect-uri 存在问题!如果它与通过 facebook 注册的应用程序域不匹配,则返回错误,并且用户返回为 0(默认用户值)。

【讨论】:

【参考方案14】:

我与getUser() 有同样的问题,它在 IE 8 中返回 0。我在做了一些研究后找到了解决方案。按照下面的链接。这就像一个魅力。

http://www.andugo.com/facebook-php-sdk-getuser-return-0-value-on-ie/

【讨论】:

这只是为我修好了。 Wtf,我应该如何解决这些奇怪的 facebook api 问题? FB api 的每一小块都需要数小时来调试..【参考方案15】:

经过几个小时的绝望,我的服务器上出现了同样的问题:如果您使用 SSL,确保端口 443 未被阻塞!我去年打开了端口,但最近我的虚拟主机似乎以某种方式进行了重置。

【讨论】:

【参考方案16】:

如果您使用新的 SDK 3.1.1 和 JS,您需要将新变量添加到名为 FB.init 的例程中

oauth : true 使用新的 OATH 2.0 协议! 然后在不允许 perms 时更新您的登录按钮,请使用范围而不是 perms

【讨论】:

【参考方案17】:

getUser() 和 PHP-SDK 如果 _REQUEST 像全局变量一样由于配置错误而被 http 服务器丢弃。我使用了错误配置的 nginx,在跟踪代码约 3 小时后,通过更改 vhost 配置解决了这个问题。

我在这里写了关于解决方案的评论:https://github.com/facebook/php-sdk/issues/418#issuecomment-2193699

希望对你有帮助。

【讨论】:

Github 上没有评论了 :( 是的,我认为问题已被删除或移至其他地方,至少有 50 多个 cmets。我的问题与 nginx 服务的几个空 _SERVER 全局变量有关。 我通过将以下代码放在库负载之上解决了这个问题。 parse_str($_SERVER['QUERY_STRING'],$_REQUEST);【参考方案18】:

当没有登录用户时,facebook->getUser() 将返回 0。 (https://developers.facebook.com/docs/reference/php/facebook-getUser/)

为解决此问题,Facebook JS SDK 提供了一个成功登录的访问令牌,您可以将其与 Facebook PHP SDK 一起使用。

下面的 javascript 将检查 Facebook 登录是否已经存在以及您的 Facebook 应用是否已获得授权:

FB.getLoginStatus(function($response) 
    if ($response.status === 'connected') 
        var uid = $response.authResponse.userID;
        var accessToken = $response.authResponse.accessToken;
        _accessServer(uid, accessToken);

     else if ($response.status === 'not_authorized') 
        _loginPopup();

     else 
        _loginPopup();
    
);

函数 _accessServer 向您的服务器打开另一个请求,发送访问令牌。

_loginPopup 函数应该打开 Facebook 登录弹出窗口,为用户请求适当的权限以“允许访问”您的应用程序。

然后,PHP 应用程序应将访问令牌传回 Facebook API:

$facebook->setAccessToken($new_access_token);
$uid = $facebook->getUser();

https://developers.facebook.com/docs/reference/php/facebook-setAccessToken/

希望对您有所帮助。

【讨论】:

【参考方案19】:

添加这一行为我在 IE9 中解决了这个问题:

header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"'); // This is the main cause to use on IE.

【讨论】:

【参考方案20】:

如果这个问题仍然与人们相关,我想贡献我的 2 美分,因为我花了很长时间才让事情正常进行。

首先,试用适合您的 SDK,无论是 PHP 还是 JS。从本质上讲,它们都做同样的事情,只是 JS 可能会更优雅地处理它(使用弹出对话框等等)。那里有很多不同的教程、手册和示例!我花了大约一周的时间才找到适合我并且可以实际使用的 1 个。找到与您计划使用的 SDK 配合使用的代码后,您就可以根据您的特定需求更改代码了。

一旦我完成了我的代码,我就开始测试它。我注意到我在本地主机上运行我的代码,我也没有从我的数组中得到任何结果。 回答您的问题:将您的代码上传到(子)域,然后重试。我的代码一直有效,但由于我没有在线,所以它不起作用。如果你已经上网了,那我的回答对你没用。

很抱歉,如果这种小故事不是真的要在 SO 上发表,但它可能会对人们有所帮助。

祝你好运!

【讨论】:

【参考方案21】:
    if ($facebook->getUser()) 
       $userProfile = $facebook->api('/me');
       // do logic
     else 
       $loginUrl = $facebook->getLoginUrl($params = array('scope' => SCOPE));
       header('Location:' . $loginUrl);
    

我是如何解决我的问题的,现在它正在向我返回用户配置文件的详细信息以供进一步处理。 (真是头疼)

【讨论】:

旁注:记得在header('Location: $url');之后调用exit;【参考方案22】:

这些都是很好的建议,但对我有用的是 Facebook 本身。多次重构代码后,我意识到这是 Facebook 上的配置问题。 以下步骤解决了我的问题。

1.) 在 Facebook 上的基本 > 应用程序下...我取消了选择,尽管您可以根据需要离开它

2.) 在权限 > 隐私下 -> 设置为公开

Permissions > Auth Token -> 设置为查询字符串

3.) 在高级 -> 身份验证 > 应用程序类型 -> 网络下

第三步才是真正解决问题的一步,虽然不完全确定为什么,希望对你有所帮助

【讨论】:

【参考方案23】:

确保在任何输出之前调用此 Facebook API 函数 getUser,因为它使用会话变量和 Cookie。如果您这样做,则无法正确发送/读取标头。

【讨论】:

【参考方案24】:

我也花了很多时间研究这个问题并找到了解决方案。可能不适合您,但 $_SERVER['QUERY_STRING'] 似乎存在一些问题,因此您需要将其设置到 $_REQUEST 数组中。

我正在使用codeigniter,发现库加载上方的以下代码有效。

parse_str($_SERVER['QUERY_STRING'],$_REQUEST);

    parse_str($_SERVER['QUERY_STRING'],$_REQUEST);
    $config = array(); 
    $config["appId"] = "63xxxxx39";
    $config["secret"] = "dexxxx3bf";
    $this->load->library('facebook',$config);

    $this->user = $user = $this->facebook->getUser();
    if ($user) 

        try 
                // Proceed knowing you have a logged in user who's authenticated.
                $user_profile = $this->facebook->api('/me');
                //print_r($user_profile);exit;
         catch (FacebookApiException $e) 
                echo '<pre>'.htmlspecialchars(print_r($e, true)).'</pre>';
                $user = null;
        
        $logout = $this->facebook->getLogoutUrl();
        $this->fb_logout = $logout;
        $this->fb_user = $user_profile;

     else 
        $login = $this->facebook->getLoginUrl(array("scope"=>"email","redirect_uri"=>"http://domain/login/login_fbmember/"));
        $this->fb_login = $login;
    


【讨论】:

【参考方案25】:

这个问题真的很奇怪。我发现问题出在 base_facebook.php 中的静态 $CURL_OPTS 数组。

尝试从这里编辑它:

  /**
   * Default options for curl.
   *
   * @var array
   */
  public static $CURL_OPTS = array(
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT        => 60,
    CURLOPT_USERAGENT      => 'facebook-php-3.2',
  );

  /**
   * Default options for curl.
   *
   * @var array
   */
  public static $CURL_OPTS = array(
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT        => 60,
    CURLOPT_USERAGENT      => 'facebook-php-3.2',
    CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4 
  );

【讨论】:

【参考方案26】:

我的具体问题的答案是,我使用的 JS SDK 和 PHP SDK 的版本之间存在不兼容,只需升级它们就解决了。

当它由多种不同的事情引起时,这个问题的症状是相似的,因此您可能会很好地通过此页面中提供的不同答案进行侦察。

【讨论】:

以上是关于为啥 Facebook PHP SDK getUser 总是返回 0?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Facebook 身份验证 SDK 在不同模式下的表现如此不同?

为啥 facebook sdk 会自动让我登录 iPhone 上安装的 facebook 应用程序?

检查用户是否喜欢页面| PHP | Facebook

facebook->getUser() 返回 0

PHP Facebook PHP SDK入门代码

facebook-php-sdk loginurl api 错误代码 100