由于Facebook的Permission流程中不推荐使用offline_access
Authentication,因此我们在未经许可的情况下解决所谓的长期访问权限问题。
在Facebook's document about the deprecation它说,服务器端OAuth生成的访问令牌将是长期存在的,但事实并非如此。
我错过了什么吗?应用设置中的一些设置?我需要使用一些特殊代码来延长访问令牌的到期时间?据我所知,对于服务器端身份验证,当用户登录时,PHP SDK的getAccessToken()
方法可以访问访问令牌,这种访问令牌很长。
答案 0 :(得分:72)
编辑(2012年8月14日):
一周前官方Facebook PHP SDK更新了。函数名称已更改为 setExtendedAccessToken ,并且确定我们实际上需要在之后销毁会话,以消除有两个活动会话的风险。
此外,该函数不再实际返回令牌,而是将其存储在持久数据中。因此,您可以使用公共函数 getAccessToken 获取新的访问令牌。从official Facebook PHP SDK github page获取新SDK以确保您是最新的。
原始答案:
我在base_facebook.php文件中添加了一个新的公共函数,该文件返回一个新的访问令牌,该令牌在60天后到期。收到普通访问令牌后,您可以向此功能发出请求。我没有测试过,但我认为你还需要在Developer App的高级设置中启用'deprecate offline_access'。
只需将此添加到facebook类中的base_facebook.php并调用它即可。它对我有用。
public function getExtendedAccessToken(){
try {
// need to circumvent json_decode by calling _oauthRequest
// directly, since response isn't JSON format.
$access_token_response =
$this->_oauthRequest(
$this->getUrl('graph', '/oauth/access_token'), array(
'client_id' => $this->getAppId(),
'client_secret' => $this->getAppSecret(),
'grant_type'=>'fb_exchange_token',
'fb_exchange_token'=>$this->getAccessToken()
)
);
} catch (FacebookApiException $e) {
// most likely that user very recently revoked authorization.
// In any event, we don't have an access token, so say so.
return false;
}
if (empty($access_token_response)) {
return false;
}
$response_params = array();
parse_str($access_token_response, $response_params);
if (!isset($response_params['access_token'])) {
return false;
}
return $response_params['access_token'];
}
答案 1 :(得分:22)
实际上是说了什么:
如果access_token是从服务器端OAuth调用生成的,则生成的access_token 将具有更长的到期时间。如果在该用户仍然存在有效access_token的情况下进行呼叫,则来自该第二次呼叫的返回的access_token将保持不变,并且仅延长到期时间。同样,在同一天多次调用此选项将仅导致第一次调用延长到期时间。
这意味着它只会比客户端生成的令牌更长,并且要接收扩展令牌(60天),您需要通过向以下位置发出请求来手动执行:
https://graph.facebook.com/oauth/access_token?
client_id=APP_ID&
client_secret=APP_SECRET&
grant_type=fb_exchange_token&
fb_exchange_token=EXISTING_ACCESS_TOKEN
由于多种原因,此令牌仍然无效,以及如何处理How-To: Handle expired access tokens博文中描述的内容。
<强>更新强>
自Aug 07, 2012起,您可以使用setExtendedAccessToken
方法扩展access_token
,而不是手动构建网址和检索详细信息。
答案 2 :(得分:10)
//使用javascript弹出facebook登录
FB.login(function(response) {
if (response.authResponse) {
var accessToken = response.authResponse.accessToken;
//以1-2小时的到期时间获得了accessstoken
//将accessstoken输入名为facebook controller的控制器
$request = $this->getRequest();
$params = $request->getParams();
$token=$params['accessToken'];
//将访问令牌延长至60天
$conf = $this->getConfigs();
$appid = $conf['fbdetails']['appid'];
$secret = $conf['fbdetails']['secret'];
$baseurl = $conf['app']['baseurl'];
//执行下面的代码后,我们会得到一个响应,其中一个令牌到期时间为60天。
$token_url = "https://graph.facebook.com/oauth/access_token?client_id=".$appid."&client_secret=".$secret."&grant_type=fb_exchange_token&fb_exchange_token=".$token;
//上面的响应用于解析。
$c = curl_init();
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($c, CURLOPT_URL, $token_url);
$contents = curl_exec($c);
$err = curl_getinfo($c,CURLINFO_HTTP_CODE);
curl_close($c);
$paramsfb = null;
parse_str($contents, $paramsfb);
//在解析上述执行代码中的内容后,将存储新的扩展accesstoken。
$user_session = new Zend_Session_Namespace('fbuser');
$user_session->access_token = $paramsfb['access_token'];
//存储到会话。
$this->_redirect('/home');
//有一个很好的编码
答案 3 :(得分:3)
通过服务器端OAuth调用生成的访问令牌将是扩展(更长)类型,您无需进行交换。它已经是一个扩展的令牌。 您必须做的唯一事情是在您的应用设置中启用“弃用离线访问”。当然,只有在以前禁用“弃用离线访问”时才需要这样做。
然后,当您通过Facebook验证用户时,您将收到一个存在60天的访问令牌。在同一天进行多次身份验证只会导致第一次身份验证延长到期时间。
答案 4 :(得分:2)
如果 PAGE 需要从不到期的访问令牌,请参阅我对类似问题的回答here
从开发者页面:
通过使用长期存在的用户访问令牌,查询[用户 ID] / accounts endpoint现在将提供访问令牌,不会 用户管理的页面过期。
答案 5 :(得分:0)
这是为了扩展页面访问令牌永不过期,并延长用户访问令牌的生命周期,在2个月后到期(“新访问令牌”)。
好的,所以花了一周时间研究,但这是我的解决方案。 在https://developers.facebook.com/tools/explorer/中确保您将manage_page作为access_token的一部分。之后,将此代码与您的应用ID,密码和重定向一起使用:
<?php
app_id = "APP_ID";
$app_secret = "APP_SECERET";
$post_login_url = "REDIRECT_URL";
$code = $_REQUEST['code'];
//Obtain the access_token with publish_stream permission
if(empty($code)){
$dialog_url= "http://www.facebook.com/dialog/oauth?"
. "client_id=" . $app_id
. "&redirect_uri=" . urlencode( $post_login_url)
. "&COMMA_SEPARATED_LIST_OF_PERMISSION_NAMES";
echo("<script>top.location.href='" . $dialog_url
. "'</script>");
}
else {
$token_url="https://graph.facebook.com/oauth/access_token?"
. "client_id=" . $app_id
. "&redirect_uri=". urlencode($post_login_url)
. "&client_secret=" . $app_secret
. "&code=" . $code;
$response = file_get_contents($token_url);
$params = null;
parse_str($response, $params);
$access_token = $params['access_token'];
echo 'access token: ' . $access_token.'<br>';
if($access_token){
$token_url="https://graph.facebook.com/oauth/access_token?"
. "client_id=" . $app_id
. "&redirect_uri=". urlencode($post_login_url)
. "&client_secret=" . $app_secret
.'&grant_type=fb_exchange_token'
. "&fb_exchange_token=" . $access_token;
$response = file_get_contents($token_url);
$access_token = $params['access_token'];
echo 'new access token: '.$access_token;
}
}*/
?>
之后复制“新访问令牌”并返回https://developers.facebook.com/tools/explorer/当您通过新访问令牌到达访问令牌字段时。 然后点击提交。在节点中,您将看到+ _ ___ 点击此处,然后向下滚动到帐户并点击该帐户。找到您需要访问令牌的页面,然后将其复制并粘贴到访问密钥字段中。单击调试,您将看到它永远不会过期。保存该令牌,只要您不重置您的应用秘密,它就会保持有效。
答案 6 :(得分:0)
受到之前答案的启发,我写了一个简单的令牌自我更新程序。首先,只需将当前令牌放在'token.sec'文件中即可。
此程序将从文件中读取令牌,如果一切正常,则使用新令牌进行更新。在其他程序中,您只需使用令牌:
$access_token = file_get_contents("token.sec");
我们在这里:
<?php
$app_id = "<your app id>";
$app_secret = "<your app secret>";
$access_token = file_get_contents("token.sec");
$token_url="https://graph.facebook.com/oauth/access_token?"
. "grant_type=fb_exchange_token"
. "&client_id=" . $app_id
. "&client_secret=" . $app_secret
. "&fb_exchange_token=" . $access_token;
$ch = curl_init($token_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if($response === false) {
die ('Curl error: ' . curl_error($ch));
}
// Close handle
curl_close($ch);
// parse the output
parse_str($response, $params);
if(!isset($params['access_token'])) {
die("No access token");
}
echo ("New token: $access_token\n");
// eveything looks OK
rename("token.sec", "token.sec.back"); // just in case
$myfile = fopen("token.sec", "w") or die("Unable to open file!");
fwrite($myfile, $access_token);
fclose($myfile);
?>
最后,我们可以在我们的crontab中添加这个,以便每个月更新一次令牌:
0 0 1 * * cd /home/<path>; php exchangeToken.php