PHP SDK:如何在用户授权应用程序后捕获访问令牌?

Bil*_*rer 1 access-token oauth-2.0 facebook-php-sdk facebook-canvas

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

我们使用Facebook教程中的PHP示例(https://developers.facebook.com/docs/appsonfacebook/tutorial/)来触发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%7CJICJwM1P_97tKmqkEO5pXDCf- 7Y&expires_in = 6008

以下是var_dump为同一页面的$ REQUEST数组显示的内容:array(3){[" _ qca"] => string(26)"P0-709927483-1291994912966"["_ _ spwitchTo5x"] => string(2)" 30"["PHPSESSID"] => string(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"]);
}
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

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

用户:0访问令牌:126736467765 | **SECRET** 签名请求:array(3){["_ qca"] => string(26)"P0-709927483-1291994912966"[" _switchTo5x"] => string(2)"30"["PHPSESSID" ] => string(26)"frugi545cdl15gjind1fnv6pq1"}

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

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

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

PCh*_*ese 13

好的,让我们再试一次.

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

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

应用程序访问令牌

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

令牌到期

PHP SDK的OAuth 2.0流程和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;
}
Run Code Online (Sandbox Code Playgroud)

新索引页码

// 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);
}
Run Code Online (Sandbox Code Playgroud)

重定向页面

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

// 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);
Run Code Online (Sandbox Code Playgroud)