1

这是在 Facebook 平台上使用新的(est)Facebook PHP SDK 的画布应用程序。

我们正在使用 Facebook 教程 (https://developers.facebook.com/docs/appsonfacebook/tutorial/) 中的 PHP 示例来触发 OAuth 对话框并让测试用户访问重定向 URL。

在重定向 URL 中,我们使用 Facebook 签名请求文档页面 (https://developers.facebook.com/docs/authentication/signed_request/) 中的 PHP 示例,我们的测试用户可以成功授权应用程序。

但是,在测试用户对应用程序进行身份验证后,我们无法捕获访问令牌及其过期时间。我们可以在附加到重定向 URL 的地址栏中看到它,但它没有出现在 $_REQUEST 数组中。如果我们将 {$access_token = $facebook->getAccessToken();} 添加到重定向 URL 页面,它会显示访问令牌的值,但它显示的值不是我们单击 Show 时看到的完整令牌字符串测试用户角色页面中的令牌(我们认为这是测试用户的正确访问令牌)。

以下是附加了访问令牌的重定向 URL 示例:http: //karmakorn.com/karmakorn/alpha20/kk-fb-auth.php#access_token=126736467765%7C2.AQDavId8oL80P5t9.3600.1315522800.1-100002908746828%7CJICJwM1XP_97 7Y&expires_in=6008

这是 var_dump 为同一页面的 $ REQUEST 数组显示的内容: array(3) { [" _qca"]=> string(26) "P0-709927483-1291994912966" ["__switchTo5x"]=> string(2) " 30" ["PHPSESSID"]=> 字符串(26) "euois02ead39ijumca7nffblh2" }

我们不知道为什么 $_REQUEST 数组与附加到 URL 的值不同,更重要的是 - 如何捕获访问令牌及其到期日期。

有人可以向我们展示他们在重定向页面上运行 parse_signed_request($signed_request, $secret) 函数后如何捕获这些数据的工作示例吗?谢谢!

附加信息:

这是 A)我们的测试索引页面和 B)我们的测试重定向页面的相关代码。如果我们使用我们的文本索引页面作为重定向 url,它会陷入死循环——因为用户永远不会被识别。

A) 索引页

// Create kk-fb app instance
$facebook = new Facebook(array(
    'appId'  => KKFB_ID,
    'secret' => KKFB_KY,
    'oauth' => true,
));

$app_id = KKFB_ID;
$secret = KKFB_KY;
$canvas_auth = 'http://karmakorn.com/karmakorn/alpha20/kk-fb-auth.php';

$auth_url = "https://www.facebook.com/dialog/oauth?" 
                . "client_id=" . $app_id 
                . "&redirect_uri=" . urlencode($canvas_auth) 
                . "&response_type=token" 
                . "&scope=email,publish_stream";

$signed_request = $_REQUEST["signed_request"];

list($encoded_sig, $payload) = explode('.', $signed_request, 2); 

$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);

if (empty($data["user_id"])) {
    echo("<script> top.location.href='" . $auth_url . "'</script>");
} else {
    echo ("Welcome User: " . $data["user_id"]);
}

B) 重定向页面

// Create kk-fb app instance
$facebook = new Facebook(array(
    'appId'  => KKFB_ID,
    'secret' => KKFB_KY,
    'oauth' => true,
));

$app_id = KKFB_ID;
$secret = KKFB_KY;

$signed_request = $_REQUEST["signed_request"];

list($encoded_sig, $payload) = explode('.', $signed_request, 2); 

$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);

$user = $facebook->getUser();
$access_token = $facebook->getAccessToken();

echo "User: $user <br>";
echo "Access Token: $access_token <br>";
echo "Signed Request: $signed_request <br>";
var_dump($_REQUEST);

以下是这些回声结果显示的内容:

用户:0 访问令牌:126736467765| **秘密** 签名请求:array(3) { [" _qca"]=> string(26) "P0-709927483-1291994912966" [" _switchTo5x"]=> string(2) "30" ["PHPSESSID" ]=> 字符串(26)“frugi545cdl15gjind1fnv6pq1”}

有趣的是,当测试用户返回索引页面时,如果条件满足,我们可以得到正确的访问令牌:

欢迎用户:100002908746828 访问令牌:126736467765|2.AQBgcyzfu75IMCjw.3600.1315544400.1-100002908746828|m5IYEm976tJAkbTLdxHAhhgKmz8

显然,我们仍然缺少一些东西!?此外,我们还需要学习如何将过期时间作为变量获取,以便我们可以将这两者都存储在我们的数据库中。

4

4 回答 4

13

好的,让我们再试一次。

服务器端与客户端身份验证

您专门使用 PHP SDK,因此您希望进行服务器端身份验证,其中身份验证代码通过 URL 通过 HTTP 发送到服务器。这将允许您在身份验证后的第一个页面加载时为用户获取访问令牌(在您的情况下为重定向页面)。您当前正在构建的 auth_url 是 setting response_type=token,这会强制重定向使用客户端身份验证模式并在 URL 片段中而不是在查询中设置令牌。您应该完全删除该参数。事实上,我强烈建议您只使用 PHP SDK 而不是自己构建该 URL。请参见下面的示例。

应用程序访问令牌

奇怪的访问令牌 126736467765| SECRET是您的应用程序访问令牌,由您的应用程序 ID 和密钥组成。getAccessToken()如果没有可用的用户访问令牌(因为某些 API 调用至少需要某种访问令牌),则返回应用程序访问令牌。这也意味着您已经通过这篇博文向全世界透露了您的密钥,因此您应该重置您的应用程序密钥,否则任何人都可以代表您进行 API 调用。如果您与他人共享访问令牌,我强烈建议您省略部分访问令牌。

代币到期

OAuth 2.0 流程和 PHP SDK 的 v3.1.1 不会让确定令牌的过期时间变得那么容易。我建议尝试进行 API 调用,如果API 调用失败并显示OAuthException. 令牌即使没有过期也可能是无效的,所以这个处理更多的情况。但是,如果您仍然想保留到期日期,您可能只想从令牌本身中提取它。如果您有过期令牌,则过期时间戳将包含在该字符串中。这是我快速组合起来提取的一个函数:

function extractExpirationFromToken($access_token) {
    $segments = explode('|', $access_token);
    if(count($segments) < 2) { return 0; }

    $segments = explode('.', $segments[1]);
    if(count($segments) < 4) { return 0; }

    $expires = $segments[3];
    $dash_pos = strrpos($expires, '-');
    if($dash_pos !== false) {
        $expires = substr($expires, 0, $dash_pos);
    }
    return $expires;
}

新索引页面代码

// Create kk-fb app instance
$facebook = new Facebook(array(
    'appId'  => KKFB_ID,
    'secret' => KKFB_KY,
));

$canvas_auth = 'http://karmakorn.com/karmakorn/alpha20/kk-fb-auth.php';

$auth_url = $facebook->getLoginUrl(array(
    'scope' => 'email,publish_stream',
    'redirect_uri' => $canvas_auth, // you could just redirect back to this index page though
));

$user = $facebook->getUser();

if (empty($user)) {
    echo("<script> top.location.href='" . $auth_url . "'</script>");
} else {
    echo ("Welcome User: " . $user);
}

重定向页面

我认为你根本不需要这个页面。您可以将用户重定向回您的原始索引页面。

// Create kk-fb app instance
$facebook = new Facebook(array(
    'appId'  => KKFB_ID,
    'secret' => KKFB_KY,
));

$user = $facebook->getUser();
$access_token = $facebook->getAccessToken();
// also copy the function definition given earlier
$expiration = extractExpirationFromToken($access_token);

echo "User: $user <br>";
echo "Access Token: $access_token <br>";
echo "Expiration: $expiration <br>";
echo "Request: <br>";
var_dump($_REQUEST);
于 2011-09-09T21:15:08.707 回答
2

例如,您可以使用 facebook 内置方法 getAccessToken();

$access_token = $facebook->getAccessToken();

这将为您提供变量的访问令牌,现在如果您将其设为空,请记住首先检查 fuid 是否被正确捕获,如果不是,您可能需要检查您的设置,确保您的“应用程序域”设置正确后,这部分非常重要,您需要重置您的应用程序密码,然后在您的身份验证代码中设置您的新值。希望这有帮助,让我知道:)

PD。还要记住在整个 php 文件或类中保持变量的范围可见。

于 2011-09-08T22:56:47.090 回答
1

问题

粘贴的access_tokenURL 中的 不是查询字符串的一部分,而是包含在 URL 片段中(在 # 之后)。URL 片段不会发送到 Web 服务器,并且只能由 Javascript 等客户端代码读取。因此 PHP SDK 只能看到http://karmakorn.com/karmakorn/alpha20/kk-fb-auth.php,这就是为什么$_REQUEST不包含access_token密钥的原因。

问题/注释

  1. 你的redirect_uri用什么?我想你想使用类似http://apps.facebook.com/your_canvas_url/
  2. 您不需要打电话给parse_signed_request自己或从签名的请求页面复制任何代码。PHP SDK 将为您做到这一点。只需致电:

    $facebook = new Facebook(array(
        'appId' => '…',
        'secret' => '…',
    ));
    $access_token = $facebook->getAccessToken();
    

可能的解决方案

  1. 还可以使用Facebook Javascript SDK。您可以首先<script>在目标页面 (kk-fb-auth.php) 中添加它的标签(有关详细信息,请参阅文档;不要忘记设置oauth: true)。JS SDK 应该设置一个 cookie(名为 fbsr_126736467765),PHP SDK 将能够通过$_REQUEST$_COOKIE在后续页面加载时读取该 cookie。
于 2011-09-09T00:10:35.430 回答
0

如果您想使用 PHP 执行此操作,您可以通过在 redirect_uri 中单独调用 Graph API 来获取用户的访问令牌。为此,您需要将索引页面中 $auth_url 的 response_type 更改为“code”或“code token”。

然后,在您的重定向页面,Facebook 将在查询字符串中添加一个“代码”参数。此 API 调用将返回完整的 access_token 和过期时间:

https://graph.facebook.com/oauth/access_token?
    client_id=YOUR_APP_ID&
    redirect_uri=YOUR_URL&
    client_secret=YOUR_APP_SECRET&
    code=$_REQUEST['code']

有关更多信息,您可以参考有关身份验证的文档

于 2011-09-09T05:10:07.980 回答