php 自 offline_access 弃用以来如何扩展访问令牌的有效性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8982025/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 05:54:56  来源:igfitidea点击:

How to extend access token validity since offline_access deprecation

phpfacebook-graph-apifacebook-php-sdkoauth-2.0facebook-oauth

提问by Rok Dominko

Since the offline_accessPermissionis deprecated in Facebook's Authenticationflow, we have problem geting the so called long lived access tokens without that permission.

由于offline_access权限在 Facebook 的身份验证流程中已弃用,因此我们无法在没有该权限的情况下获取所谓的长期访问令牌。

In Facebook's document about the deprecationit says, that server side OAuth generated access tokens will be long lived, but they are not.

Facebook 关于弃用的文档中,它说服务器端 OAuth 生成的访问令牌将长期存在,但事实并非如此。

Am I missing something? Some setting in app settings? Some special code I need to use to extend expiration time of access tokens? As I understand the documentation, for server side authentication, the access token wich can be accessed by getAccessToken()method of PHP SDK when the user is logged in is long lived.

我错过了什么吗?应用程序设置中的一些设置?我需要使用一些特殊代码来延长访问令牌的到期时间?据我了解文档,对于服务器端身份验证,getAccessToken()用户登录时可以通过PHP SDK 方法访问的访问令牌是长期存在的。

回答by Marc Hoogvliet

Edit (August 14th 2012):
A week ago the official Facebook PHP SDK was updated. The function name was changed to setExtendedAccessToken, and it was decided we actually needed to destroy the session afterwards, to remove the risk of having two active sessions.
Also, the function no longer actually returns the token, but instead stores it within the persistant data. You can therefore get the new access token with the public function getAccessTokenafterwards. Grab the new SDK from official Facebook PHP SDK github pageto make sure you're up to date.

编辑(2012 年 8 月 14 日):
一周前官方 Facebook PHP SDK 已更新。函数名称更改为setExtendedAccessToken,并决定我们实际上需要在之后销毁会话,以消除具有两个活动会话的风险。
此外,该函数不再实际返回令牌,而是将其存储在持久数据中。因此,您可以在之后使用公共函数getAccessToken获取新的访问令牌。从官方 Facebook PHP SDK github 页面获取新的 SDK,以确保您是最新的。

Original Answer:

原答案:

I have added a new public function to the base_facebook.php file, which returns an new access token which expires in 60 days. You can make a request to this function after you've received the normal access token. I've not tested, but I assume you also need to enable 'deprecate offline_access" in your Advanced settings of the Developer App.

我在 base_facebook.php 文件中添加了一个新的公共函数,它返回一个新的访问令牌,该令牌在 60 天后到期。您可以在收到普通访问令牌后向此函数发出请求。我没有测试过,但我假设您还需要在开发者应用程序的高级设置中启用“deprecate offline_access”。

Just add this to your base_facebook.php inside the facebook class and make a call to it. It works for me.

只需将它添加到 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'];
}

回答by Juicy Scripter

Actually what was said:

原来是这么说的:

If the access_token is generated from a server-side OAuth call, the resulting access_token will have the longer expiration time. If the call is made while there is still a valid access_token for that user, the returned access_token from this second call will remain the same and only the expiration time will be extended. Again, calling this multiple times during the same day will result only in the first call extending the expiration time.

如果 access_token 是从服务器端 OAuth 调用生成的,则生成的 access_token将具有更长的到期时间。如果在该用户仍有有效的 access_token 时进行调用,则第二次调用返回的 access_token 将保持不变,只会延长到期时间。同样,在同一天多次调用它只会导致第一次调用延长到期时间。

Which means that it will be just longer than client-side generated token, and to receive extended token (60 days) you need do it manually by issuing request to:

这意味着它将比客户端生成的令牌长,并且要接收扩展令牌(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

This token can still became invalid for several reasons, and how to handle this described in How-To: Handle expired access tokensblog post.

由于多种原因,此令牌仍然可能无效,以及如何处理此问题,请参阅 How-To:处理过期的访问令牌博客文章。

Update:
As of Aug 07, 2012you can use setExtendedAccessTokenmethod to extend access_tokeninstead of manually constructing URL and retrieving details.

更新:
截至2012 年 8 月 7 日,您可以使用setExtendedAccessToken方法来扩展access_token而不是手动构建 URL 和检索详细信息。

回答by gokul bs

//using a javascript for popup for facebook login

//使用javascript弹出facebook登录

FB.login(function(response) {

            if (response.authResponse) {

                   var accessToken = response.authResponse.accessToken;

//got the accesstoken with 1-2 hours expire time

//获得1-2小时过期时间的accesstoken

//got the accesstoken into a controller called facebook controller

//将访问令牌放入一个名为facebook控制器的控制器中

        $request = $this->getRequest();
        $params = $request->getParams();
        $token=$params['accessToken'];

//taking the access token to extend to 60days

// 将访问令牌延长至 60 天

        $conf = $this->getConfigs();
        $appid = $conf['fbdetails']['appid'];
        $secret = $conf['fbdetails']['secret'];
        $baseurl = $conf['app']['baseurl'];

//After the execution of below code , we will have a response with acess token expire time to 60days.

//执行以下代码后,我们将收到访问令牌过期时间为 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;

// Above response is given for parsing.

// 以上响应用于解析。

        $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);

//after the parsing the contents in the above execution code the new extended accesstoken is stored.

//解析上述执行代码中的内容后,存储新的扩展访问令牌。

        $user_session = new Zend_Session_Namespace('fbuser');
        $user_session->access_token = $paramsfb['access_token'];

//stored to session.

//存储到会话中。

        $this->_redirect('/home');

//Have a nice coding

//有一个很好的编码

回答by Robert Kajic

An access token generated through a server-side OAuth call will be of the extended (longer) kind and you don't need to exchange it. It is already an extended token. The only thing you must do is enable "Deprecate offline access" in your app settings. This is of course only necessary if "Deprecate offline access" was previously disabled.

通过服务器端 OAuth 调用生成的访问令牌将是扩展的(更长的)类型,您不需要交换它。它已经是一个扩展令牌。您唯一必须做的就是在您的应用设置中启用“弃用离线访问”。这当然只有在“弃用离线访问”之前被禁用时才需要。

Then, when you authenticate users through Facebook you will receive an access token that lives for 60 days. Authenticating multiple times during the same day will result only in the first authentication extending the expiration time.

然后,当您通过 Facebook 对用户进行身份验证时,您将收到一个有效期为 60 天的访问令牌。同一天多次认证只会导致第一次认证延长到期时间。

回答by Pete

Should you need an access token that NEVERexpires for a PAGE, see my answer to a similar question here

如果您需要一个PAGE永不过期的访问令牌,请在此处查看我对类似问题的回答

From the developers page:

从开发人员页面:

By using a long-lived user access token, querying the [User ID]/accounts endpoint will now provide page access tokensthat do not expire for pagesthat a user manages.

通过使用令牌的长期用户访问,查询[用户名] /占端点现在将提供页面访问令牌没有为网页过期,用户管理。

回答by Aaron Dartt

this is for extending pages access token to expiring never, and extending the life of user access tokens expiring after 2 months(the 'new access token').

这是为了将页面访问令牌扩展到永不过期,并延长 2 个月后到期的用户访问令牌的寿命(“新访问令牌”)。

Ok so it took about a week of research but here is my solution. in the https://developers.facebook.com/tools/explorer/make sure that you have manage_page as part of your access_token. after that use this code with your app id, secret, and redirect:

好的,所以花了大约一周的研究时间,但这是我的解决方案。在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;

        }
    }*/

?>

After that copy the 'new access token' and go back to https://developers.facebook.com/tools/explorer/When you get there past in your new access token into the the access token field. Then click submit. After that in the node you will see a +____click on this and scroll down to the accounts and click that. find the page that you need the access token for and copy and paste it into the access key field. click debug and you will see that it will never expire. save that token it will stay valid as long as you do not reset your apps secret.

之后,复制“新访问令牌”并返回到 https://developers.facebook.com/tools/explorer/当您在新访问令牌中进入访问令牌字段时。然后点击提交。之后,在节点中,您将看到 + ____单击此按钮并向下滚动到帐户并单击该按钮。找到您需要访问令牌的页面,然后将其复制并粘贴到访问密钥字段中。单击调试,您将看到它永远不会过期。保存该令牌,只要您不重置您的应用程序机密,它就会保持有效。

回答by Sung Kim

Inspired by previous answers, I wrote a simple token self-renewal program. First, just put your current token in the 'token.sec' file.

受之前答案的启发,我编写了一个简单的令牌自我更新程序。首先,只需将您当前的令牌放入“token.sec”文件中。

This program will read a token from the file, and update with a new token if everything is OK. In other programs, you just need to use the token:

该程序将从文件中读取令牌,如果一切正常,则使用新令牌更新。在其他程序中,您只需要使用令牌:

$access_token = file_get_contents("token.sec");

Here we are:

我们到了:

<?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);
?>

Finally, we can add this in our crontab to renew the token once per momth:

最后,我们可以将它添加到我们的 crontab 中,以每月更新一次令牌:

0 0 1 * * cd /home/<path>; php exchangeToken.php