0

几个月来,我一直在为网站使用 Facebook 登录(PHP SDK),没有出现任何问题。几天以来,我们遇到了问题。

这是代码

    $fbconfig['appid' ]     = "...";
    $fbconfig['secret']     = "...";
    $fbconfig['baseurl']    = "myurl/index.php";

    $facebook = new Facebook(array(
      'appId'  => $fbconfig['appid'],
      'secret' => $fbconfig['secret'],
      'cookie' => true,
    ));

    $user       = $facebook->getUser();

    $loginUrl   = $facebook->getLoginUrl(
            array(
                'scope'         => 'email,user_likes,user_birthday',
                'redirect_uri'  => $fbconfig['baseurl']
            )
    );

    $logoutUrl  = $facebook->getLogoutUrl(
            array(
                'next'  => $fbconfig['baseurl'].'?f=logout'
            )
    );
    if ($user) {
     ....try {
                $fb_user_infos_ar = $facebook->api('/me');
        }

        catch (FacebookApiException $e) {

            $facebook->destroySession();
            $user = null;
        }
    }

if (isset($fb_user_infos_ar)){
do something...
}
else{
show facebook login button
}

我们遇到的问题是登录似乎有效,但过了一段时间(大部分时间甚至几秒钟后)用户不再被识别为登录到 Facebook($user 为 0 并显示登录按钮) .

过去几天 Facebook 规则或浏览器是否有任何变化可以解释这种行为?我已经尝试过使用 firefox 和 chrome 获得相同的结果。由于我的 PHP sdk 已经使用了几个月,所以我也尝试了最新的一个,结果相同。我还注意到,在上一个版本的示例中,不再提及“base_url”,你知道为什么吗?

评论后编辑

从评论中得到一些提示后,我试图调试正在发生的事情;令牌似乎没有失效;事实上,当我再次登录时,我仍然会在几小时前得到一个生成的令牌。

然而,出于某种原因,有时用户被认为未登录(基本上 $facebook->getUser() 为假),即使他已登录。

正如 complex857 所建议的那样,原因之一可能是 facebook 在与我的网站交谈时遇到问题;在过去的几天里,我实际上注意到该站点的一般性能损失,在今天的调试会话之后,我可以说当涉及到 Facebook 活动时会出现性能损失。特别是我测量了这条指令的执行时间:

$fb_user_infos_ar = $facebook->api('/me');

大约是5秒;我不知道之前花了多长时间,但我想太多了;你怎么看?

关于可能的 cookie 问题,我应该检查什么?

回答后编辑2

更多详细信息:如果在 API 调用期间出现问题(捕获部分),我曾经用

$facebook->destroySession();

这就是用户注销的原因。有时实际上不需要销毁会话(例如,如果由于网络问题导致超时),所以我应该根据错误处理异常。

据我了解,Andy Jones 提供的一段代码

echo "error code = " . $e->getCode() . " error = " . $e->getMessage() . "\n";

适用于 CURL 错误但不适用于其他类型的错误(例如令牌过期)。例如,如果我在令牌因密码更改而无效时打印出异常,我会得到:

FacebookApiException Object ( [result:protected] => Array ( [error] => Array ( [message] => 验证访问令牌时出错:由于用户更改了密码,会话已失效。[type] => OAuthException [code] ] => 190 [error_subcode] => 460)

    )

[message:protected] => Error validating access token: The session has been invalidated because the user has changed the password.
[string:Exception:private] => 
[code:protected] => 0 ....

$e->getCode() 只给我 0 而不是 190。

以下是错误列表:https ://developers.facebook.com/docs/reference/api/errors/我认为在我的特定情况下处理该过程的一种简单方法是:如果代码破坏了 facebook 会话是190或102,否则尝试重复操作。你怎么看,哪一段是一般处理这个问题的最佳实践代码?

另一个问题:使用 $e->getMessage() 记录异常时,我收到“验证访问令牌时出错:由于用户更改了密码,会话已失效。” 但我确信对于我当时使用的用户(我自己的)我没有更改 facebook 密码。这怎么可能发生?即使在其他情况下(例如,当令牌处于其自然到期日期时)也会产生相同的消息吗?

谢谢。

4

1 回答 1

0

有很多事情可能会出错,您应该检查根本原因并采取适当的措施......

} catch (FacebookApiException $e) {
  $facebook->destroySession();
  $user = null;
}

目前,您只是破坏会话并继续前进。但是,异常有很多精彩的数据。从FacebookBase.php中,您将在函数makeRequest中找到它抛出FacebookAPIException.

$e = new FacebookApiException(array(
    'error_code' => curl_errno($ch),
    'error' => array(
    'message' => curl_error($ch),
    'type' => 'CurlException',
    )));
throw $e;

最重要的是,您想要检查curl_errno来自curl_error. 你可以这样做...

echo "error code = " . $e->getCode() . " error = " . $e->getMessage() . "\n";

Curl 会告诉你错误代码的解释出了什么问题。对于一些更常见的错误(6 = 无解析主机,7 = 无连接,28 = 超时),这可能表明您的网络连接、Facebook 或介于两者之间的某个地方存在问题。或者 Facebook API 可能只是很忙并且没有快速响应。最常见的反应就是再试一次。

如果您看到错误代码 0(零) - 没有错误 - 这意味着 Facebook 调用正常,但 Facebook 只是没有返回任何数据。这是 Facebook 的错误。

如果您看到其他错误,请查看错误代码的说明,然后从那里开始。

Facebook Graph API 不保证正常运行时间。您应该考虑尽可能多地缓存并在出现错误时处理它们。我知道这对程序员来说是更多的工作,但这是我们正在走向的相互连接的世界。

于 2013-11-02T15:45:58.230 回答