Как продлить срок действия токена с момента отмены офлайн_access

Поскольку разрешение offline_access устарело в потоке аутентификации Facebook, у нас есть проблема с получением так называемых долгоживущих токенов доступа без этого разрешения.

В документе Facebook об устаревании он говорит, что на стороне сервера OAuth сгенерированные токены доступа будут долговечными, но это не так.

Я что-то упускаю? Некоторые настройки в настройках приложения? Какой-то специальный код, который мне нужно использовать для продления срока действия токенов доступа? Поскольку я понимаю документацию, для аутентификации на стороне сервера токен доступа, к которому можно получить метод getAccessToken() PHP SDK при getAccessToken() пользователя в систему, долговечен.

Редактировать (14 августа 2012 года):
Неделю назад был обновлен официальный PHP PHP SDK. Имя функции было изменено на setExtendedAccessToken , и было решено, что нам действительно необходимо уничтожить сеанс впоследствии, чтобы удалить риск наличия двух активных сеансов.
Кроме того, функция больше не возвращает токен, а сохраняет его в постоянных данных. Таким образом, вы можете получить новый токен доступа с публичной функцией getAccessToken . Возьмите новый SDK с официальной страницы Facebook PHP SDK github, чтобы убедиться, что вы в курсе.

Оригинальный ответ:

Я добавил новую публичную функцию в файл base_facebook.php, который возвращает новый токен доступа, срок действия которого истекает через 60 дней. Вы можете сделать запрос к этой функции после того, как получили нормальный токен доступа. Я не тестировал, но предполагаю, что вам также нужно включить «deprecate offline_access» в ваших дополнительных настройках приложения Developer.

Просто добавьте это в свой base_facebook.php внутри класса facebook и вызовите его. Меня устраивает.

  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']; } 

Фактически, что было сказано:

Если 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 tolens tokens .

Обновить:
По состоянию на 07 августа 2012 года вы можете использовать метод setExtendedAccessToken для расширения access_token вместо ручного создания URL-адреса и получения сведений.

// использование javascript для всплывающего окна для входа в facebook

 FB.login(function(response) { if (response.authResponse) { var accessToken = response.authResponse.accessToken; 

// получил accesstoken с истечением 1-2 часов

// получил accesstoken в контроллер под названием 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'); 

// Имеем хорошее кодирование

Маркер доступа, сгенерированный с помощью вызова OAuth на стороне сервера, будет иметь расширенный (более длинный) вид, и вам не нужно его обменивать. Это уже расширенный токен. Единственное, что вы должны сделать, это включить «Неактуальный автономный доступ» в настройках вашего приложения. Это, конечно, необходимо только в том случае, если ранее отключен режим «Отмена автономного доступа».

Затем, когда вы аутентифицируете пользователей через Facebook, вы получите токен доступа, который живет в течение 60 дней. Аутентификация нескольких раз в течение того же дня приведет только к первой аутентификации, продлевающей срок действия.

Если вам нужен токен доступа, который НИКОГДА не истекает для PAGE , см. Мой ответ на аналогичный вопрос здесь

На странице разработчиков:

Используя долгоживущий токен доступа пользователя, запрос к конечной точке [Идентификатор пользователя] / учетных записей теперь предоставит токены доступа к странице, которые не истекают для страниц, которыми управляет пользователь.

это означает, что токены доступа к страницам не исчерпаются, и продлевает срок службы токенов доступа пользователя, истекающих через 2 месяца («новый токен доступа»).

Хорошо, поэтому потребовалось около недели исследований, но вот мое решение. в https://developers.facebook.com/tools/explorer/ убедитесь, что у вас есть manage_page как часть вашего access_token. после этого используйте этот код с идентификатором вашего приложения, секретным и перенаправляемым:

 <?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/. Когда вы доберетесь до вашего нового токена доступа в поле токена доступа. Затем нажмите «Отправить». После этого в узле вы увидите + _ ___ щелчок по этому значку и прокрутите вниз до учетных записей и нажмите на него. найдите страницу, на которой нужен токен доступа, и скопируйте ее и вставьте в поле ключа доступа. нажмите кнопку «Отладка», и вы увидите, что она никогда не истечет. сохраните этот токен, он останется действительным до тех пор, пока вы не сбросите секрет приложений.

Вдохновленный предыдущими ответами, я написал простую программу самообновления токенов. Во-первых, просто поместите свой текущий токен в файл 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