这是使用新的(est)Facebook PHP SDK在Facebook平台上的画布应用程序。
我们正在使用Facebook教程(https://developers.facebook.com/docs/appsonfacebook/tutorial/)中的PHP示例来触发OAuth对话框并让测试用户访问重定向网址。
在重定向网址,我们使用Facebook签名请求文档页面(https://developers.facebook.com/docs/authentication/signed_request/)中的PHP示例,我们的测试用户可以成功授权该应用。
但是,在测试用户验证应用程序后,我们无法捕获访问令牌及其过期。我们可以在附加到重定向URL的地址栏中看到它,但它不会显示在$ _REQUEST数组中。如果我们将{$ access_token = $ facebook-> getAccessToken();}添加到重定向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”[“__switchTo5x”] => 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"]);
}
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 | ** SECRET ** 签名请求: array(3){[“_ qca”] =&gt; string(26)“P0-709927483-1291994912966”[“ _switchTo5x”] =&gt; string(2)“30”[“PHPSESSID”] =&gt; string(26)“frugi545cdl15gjind1fnv6pq1”}
有趣的是,当测试用户返回索引页面时,if条件得到满足并且我们可以获得正确的访问令牌:
欢迎用户:100002908746828 访问令牌:126736467765 | 2.AQBgcyzfu75IMCjw.3600.1315544400.1-100002908746828 | m5IYEm976tJAkbTLdxHAhhgKmz8
显然,我们仍然缺少一些东西!?此外,我们还需要学习如何将过期时间作为变量,以便我们可以将这两者存储在我们的数据库中。
答案 0 :(得分:13)
好的,让我们再试一次。
您专门使用PHP SDK,因此您希望进行服务器端身份验证,其中身份验证代码通过URL通过HTTP发送到服务器。这将允许您在auth之后的第一页加载(在您的情况下,重定向页面)中为用户获取访问令牌。您当前正在构建的auth_url正在设置response_type=token
,这会强制重定向使用客户端身份验证模式,并在URL片段中而不是在查询中设置令牌。您应该完全删除该参数。事实上,我强烈建议您只使用PHP SDK而不是自己构建该URL。见下面的例子。
奇怪的访问令牌126736467765 | SECRET 是您的应用程序访问令牌,它由您的应用程序ID和密钥组成。如果没有可用的用户访问令牌,则getAccessToken()
返回应用程序访问令牌(因为某些API调用至少需要某种访问令牌)。这也意味着您已通过此博客文章向全世界透露了您的密钥,因此您应reset your app secret,否则任何人都可以代表您拨打API电话。如果您与他人分享,我强烈建议您取消访问令牌的部分内容。
PHP SDK的OAuth 2.0流程和v3.1.1无法轻松确定令牌的到期时间。我建议尝试进行API调用,然后refreshing the token如果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);
答案 1 :(得分:2)
您可以在方法getAccessToken()中使用facebook build;
$access_token = $facebook->getAccessToken();
这将为您提供变量的访问令牌,现在如果您将其变为空,请记住首先检查fuid是否正常捕获,如果不是,您可能需要查看您的设置,请确保“ “App Domain”设置正确设置此部分非常重要您需要重置应用程序密钥,然后在您的身份验证代码中设置新值。希望这个帮助,让我知道:)。
概率pd。还要记住在整个php文件或类中保持变量的范围。
答案 2 :(得分:1)
粘贴的网址中的access_token
不是查询字符串的一部分,而是包含在网址片段中(在#之后)。 URL片段不会发送到Web服务器,只能由Javascript等客户端代码读取。因此,PHP SDK仅显示http://karmakorn.com/karmakorn/alpha20/kk-fb-auth.php,这就是$_REQUEST
不包含access_token
密钥的原因。
您不需要自己致电parse_signed_request
或从已签名的请求页面复制任何代码。 PHP SDK将为您完成。请致电:
$facebook = new Facebook(array(
'appId' => '…',
'secret' => '…',
));
$access_token = $facebook->getAccessToken();
<script>
标记(有关详细信息,请参阅the docs;请不要忘记设置oauth: true
)。 JS SDK应该设置一个cookie(名为fbsr_126736467765),PHP SDK可以在后续页面加载时通过$_REQUEST
或$_COOKIE
读取。答案 3 :(得分: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']
有关详细信息,请参阅docs on authentication。