Як оновити маркер за допомогою клієнта Google API?


91

Я бавився з API Google Analytics (V3) і стикався з помилками som. По-перше, все налаштовано правильно і працює з моїм тестовим акаунтом. Але коли я хочу отримати дані з іншого ідентифікатора профілю (того самого облікового запису Google Accont / GA), я отримую помилку 403. Дивна річ у тому, що дані з деяких облікових записів GA повертатимуть дані, тоді як інші генерують цю помилку.

Я ще раз відкликав маркер і автентифікувався, і тепер, схоже, я можу захопити дані з усіх своїх облікових записів. Проблема вирішена? Ні. Оскільки термін дії ключа доступу закінчується, я знову зіткнуся з тією ж проблемою.

Якщо я все зрозумів правильно, можна використовувати resfreshToken, щоб отримати нову аутентифікаціюTooken.

Проблема в тому, що коли я запускаю:

$client->refreshToken(refresh_token_key) 

повертається така помилка:

Error refreshing the OAuth2 token, message: '{ "error" : "invalid_grant" }'

Я перевірив код методу refreshToken і відстежив запит до файлу “apiOAuth2.php”. Всі параметри надіслані правильно. Тип grant_ жорстко закодований як 'refresh_token' в рамках методу, тому мені важко зрозуміти, що не так. Масив параметрів виглядає так:

Array ( [client_id] => *******-uqgau8uo1l96bd09eurdub26c9ftr2io.apps.googleusercontent.com [client_secret] => ******** [refresh_token] => 1\/lov250YQTMCC9LRQbE6yMv-FiX_Offo79UXimV8kvwY [grant_type] => refresh_token )

Процедура така.

$client = new apiClient();
$client->setClientId($config['oauth2_client_id']);
$client->setClientSecret($config['oauth2_client_secret']);
$client->setRedirectUri($config['oauth2_redirect_uri']);
$client->setScopes('https://www.googleapis.com/auth/analytics.readonly');
$client->setState('offline');

$client->setAccessToken($config['token']); // The access JSON object.

$client->refreshToken($config['refreshToken']); // Will return error here

Це помилка, чи я щось зовсім неправильно зрозумів?


Не знаю, чи це помилка, чи щось інше, але зараз я оновлюю маркер доступу, використовуючи необроблений запит CURL http, і він працює нормально.
gremo

Seorch ... ти це вже зрозумів? Те саме питання тут.
Брайан Вандербуш

@gremo не могли б ви поділитися необробленим запитом CURL http, який ви використовували тут? Було б дуже корисно. Дякую!
Silver Ringvee

Відповіді:


76

Тож я нарешті зрозумів, як це зробити. Основна ідея полягає в тому, що ви маєте маркер, який отримуєте при першому запиті на автентифікацію. Цей перший маркер має маркер оновлення. Термін дії першого оригінального маркера закінчується через годину. Через годину вам потрібно використовувати маркер оновлення з першого маркера, щоб отримати новий корисний маркер. Ви використовуєте $client->refreshToken($refreshToken)для отримання нового маркера. Я називатиму це "тимчасовим маркером". Вам потрібно також зберегти цей тимчасовий маркер, оскільки через годину він також закінчується, і зверніть увагу, що з ним не пов’язаний маркер оновлення. Для того, щоб отримати новий тимчасовий маркер, вам потрібно скористатися методом, який ви використовували раніше, і використати оновлення першого маркера. Я вклав код нижче, що потворно, але я новий у цьому ...

//pull token from database
$tokenquery="SELECT * FROM token WHERE type='original'";
$tokenresult = mysqli_query($cxn,$tokenquery);
if($tokenresult!=0)
{
    $tokenrow=mysqli_fetch_array($tokenresult);
    extract($tokenrow);
}
$time_created = json_decode($token)->created;
$t=time();
$timediff=$t-$time_created;
echo $timediff."<br>";
$refreshToken= json_decode($token)->refresh_token;


//start google client note:
$client = new Google_Client();
$client->setApplicationName('');
$client->setScopes(array());
$client->setClientId('');
$client->setClientSecret('');
$client->setRedirectUri('');
$client->setAccessType('offline');
$client->setDeveloperKey('');

//resets token if expired
if(($timediff>3600)&&($token!=''))
{
    echo $refreshToken."</br>";
    $refreshquery="SELECT * FROM token WHERE type='refresh'";
    $refreshresult = mysqli_query($cxn,$refreshquery);
    //if a refresh token is in there...
    if($refreshresult!=0)
    {
        $refreshrow=mysqli_fetch_array($refreshresult);
        extract($refreshrow);
        $refresh_created = json_decode($token)->created;
        $refreshtimediff=$t-$refresh_created;
        echo "Refresh Time Diff: ".$refreshtimediff."</br>";
        //if refresh token is expired
        if($refreshtimediff>3600)
        {
            $client->refreshToken($refreshToken);
        $newtoken=$client->getAccessToken();
        echo $newtoken."</br>";
        $tokenupdate="UPDATE token SET token='$newtoken' WHERE type='refresh'";
        mysqli_query($cxn,$tokenupdate);
        $token=$newtoken;
        echo "refreshed again";
        }
        //if the refresh token hasn't expired, set token as the refresh token
        else
        {
        $client->setAccessToken($token);
           echo "use refreshed token but not time yet";
        }
    }
    //if a refresh token isn't in there...
    else
    {
        $client->refreshToken($refreshToken);
        $newtoken=$client->getAccessToken();
        echo $newtoken."</br>";
        $tokenupdate="INSERT INTO token (type,token) VALUES ('refresh','$newtoken')";
        mysqli_query($cxn,$tokenupdate);
        $token=$newtoken;
        echo "refreshed for first time";
    }      
}

//if token is still good.
if(($timediff<3600)&&($token!=''))
{
    $client->setAccessToken($token);
}

$service = new Google_DfareportingService($client);

52
Замість перевірки на 3600 секунд, вам слід використовувати $ client-> isAccessTokenExpired ()
Gaurav Gupta

2
Невелике оновлення. У останній версії, коли ви запитуєте маркер оновлення, новий маркер доступу, який повертається, тепер поставляється з новим маркером оновлення. Отже, по суті, ви можете використовувати оновлений маркер json, щоб замінити попередній маркер json, і не потрібно більше зберігати початковий маркер доступу. .
skidadon

1
Зверніть увагу, що $client->isAccessTokenExpired()все одно буде перевірятися лише час, проведений локально, щоб перевірити, чи вважається, що термін дії маркера минув. Можливо, термін дії маркера все-таки закінчився, і локальна програма дійсно буде знати лише тоді, коли спробує його використовувати. У цьому випадку клієнт API поверне виняток і не оновить маркер автоматично.
Джейсон

44

Проблема в маркері оновлення:

[refresh_token] => 1\/lov250YQTMCC9LRQbE6yMv-FiX_Offo79UXimV8kvwY

Коли рядок з '/'отримує json encoded, він захищений за допомогою '\', отже, вам потрібно його видалити.

Токен оновлення у вашому випадку має бути:

1/lov250YQTMCC9LRQbE6yMv-FiX_Offo79UXimV8kvwY

Я припускаю, що ви зробили, це те, що ви надрукували рядок json, який Google відправив назад, скопіював і вставив маркер у ваш код, тому що якщо ви json_decodeце зробите, то він правильно видалить '\'для вас!


1
дивовижна згадка, зробила мій день! збережені години!
Мірча Санду

Ти врятував мій день!
Труонг Данг,

Я хотів би, щоб я проголосував за це 100 разів. Я збирався зробити отвір у стіні за допомогою клавіатури після того, як кілька годин дивився на повідомлення "поганий грант", спробувавши абсолютно все, щоб маркер працював. Наворочуючи людину Google, навіщо використовувати скісні риски, просто чому?
Аскерман

18

ось фрагмент для встановлення маркера, перед цим переконайтесь, що тип доступу має бути встановлений в автономному режимі

if (isset($_GET['code'])) {
  $client->authenticate();
  $_SESSION['access_token'] = $client->getAccessToken();
}

Оновити маркер

$google_token= json_decode($_SESSION['access_token']);
$client->refreshToken($google_token->refresh_token);

це оновить ваш маркер, вам доведеться оновити його протягом сесії, щоб ви могли це зробити

 $_SESSION['access_token']= $client->getAccessToken()

1
ти встиг мені це з цим :) велике спасибі, набагато простіше, ніж я думав, це буде так, як я витрачаю багато часу, нікуди не потрапляючи: D
TB Ygg

16

Тип доступу слід встановити на offline. stateє змінною, яку ви встановлюєте для власного використання, а не для використання API.

Переконайтеся, що у вас остання версія бібліотеки клієнта, і додайте:

$client->setAccessType('offline');

Пояснення параметрів див. У розділі Формування URL-адреси .


Дякую jk. Я завантажив останню версію та скасував доступ до програми для свого облікового запису. Потім я ще раз надав доступ і зберігав accessToken та refreshToken. Справа в тому, що мені завжди давали refreshToken, навіть якщо setAccessType було пропущено. У будь-якому випадку, коли я запускаю $ client-> refreshToken (refresh-token-key), я все одно отримую помилку "invalid_grant". Я перевірив auth-url, і за замовчуванням "примусово". Якщо я змінив його на "авто" та запустив метод автентифікації, я не перенаправлятимусь, оскільки я вже надав доступ. Але respons - це accessToken без оновлення. Будь-які ідеї?
seorch.me

@ seorch.me Звучить божевільно, але чи можливо, що вам потрібно встановити новий $client( $client = new apiClient();), щоб використовувати маркер оновлення?
jk.

1
@ seorch.me, який ви повинні встановити $client->setApprovalPrompt('force'), а також $client->setAccessType('offline')отримати новий маркер оновлення під час авторизації. Не змушуючи користувача затверджувати обсяг доступу, Google припускає, що ви продовжуватимете використовувати старий маркер оновлення.
Джейсон

14

Відповідь, опублікована @ uri-weg, спрацювала для мене, але оскільки я не знайшов його пояснень дуже чіткими, дозвольте мені трохи її переформулювати.

Під час першої послідовності дозволів доступу у зворотному дзвінку, коли ви дійдете до точки, де ви отримаєте код автентифікації, ви також повинні зберегти маркер доступу та маркер оновлення .

Причиною є те, що google api надсилає вам маркер доступу з маркером оновлення лише під час запиту дозволу на доступ. Наступні маркери доступу будуть надіслані без жодного маркера оновлення (якщо ви не використовуєте цю approval_prompt=forceопцію).

Отриманий токен оновлення вперше залишається дійсним, поки користувач не скасує дозвіл на доступ.

У спрощеному php прикладом послідовності зворотного виклику може бути:

// init client
// ...

$authCode = $_GET['code'];
$accessToken = $client->authenticate($authCode);
// $accessToken needs to be serialized as json
$this->saveAccessToken(json_encode($accessToken));
$this->saveRefreshToken($accessToken['refresh_token']);

А пізніше, в спрощеному php, послідовність з'єднання буде такою:

// init client
// ...

$accessToken = $this->loadAccessToken();
// setAccessToken() expects json
$client->setAccessToken($accessToken);

if ($client->isAccessTokenExpired()) {
    // reuse the same refresh token
    $client->refreshToken($this->loadRefreshToken());
    // save the new access token (which comes without any refresh token)
    $this->saveAccessToken($client->getAccessToken());
}

ідеально, багато працював. єдине, що я б сказав, це те, що ви повинні пояснити, що вам потрібно передавати об'єкт json не просто маркер як рядок.
Олівер Байєс-Шелтон,

@ OliverBayes-Shelton Привіт. Дякую. Я вважав, що цього // setAccessToken() expects jsonдостатньо. Або це стосується іншої частини коду?
Daishi

Для мене це чудово працює, але чи знаєте ви, чи обробляє цей код ситуації, коли термін дії маркера закінчується через перевищення ліміту в 50 оновлення маркера? Детальну інформацію про „закінчення
Бьорн,

Здається, що остання версія 2.0 тепер повертає маркер оновлення в масиві маркерів доступу. Це означає, що збереження маркера доступу також зберігає маркер оновлення, оскільки маркер оновлення включений. У відповідь на те, що термін оновлення закінчується, я припускаю, що його потрібно було б протестувати та обробляти явно - пам’ятайте, що обмеження 50 - це "на користувача на клієнта", тобто це 50 на кожного клієнта, тож ви навряд чи зможете його досягти, особливо якщо ви використовуєте включені області для поєднання лексем.
Brian C

8

Ось код, який я використовую у своєму проекті, і він працює нормально:

public function getClient(){
    $client = new Google_Client();
    $client->setApplicationName(APPNAME);       // app name
    $client->setClientId(CLIENTID);             // client id
    $client->setClientSecret(CLIENTSECRET);     // client secret 
    $client->setRedirectUri(REDIRECT_URI);      // redirect uri
    $client->setApprovalPrompt('auto');

    $client->setAccessType('offline');         // generates refresh token

    $token = $_COOKIE['ACCESSTOKEN'];          // fetch from cookie

    // if token is present in cookie
    if($token){
        // use the same token
        $client->setAccessToken($token);
    }

    // this line gets the new token if the cookie token was not present
    // otherwise, the same cookie token
    $token = $client->getAccessToken();

    if($client->isAccessTokenExpired()){  // if token expired
        $refreshToken = json_decode($token)->refresh_token;

        // refresh the token
        $client->refreshToken($refreshToken);
    }

    return $client;
}

6

Був той самий випуск; мій сценарій, який працював учора, з якихось дивних причин не зробив сьогодні. Без змін.

Очевидно, це було тому, що мій системний годинник вимкнувся на 2,5 (!!) секунди, синхронізація з NTP це виправила.

Див. Також: https://code.google.com/p/google-api-php-client/wiki/OAuth2#Solving_invalid_grant_errors


Ця відповідь мені дуже допомогла, чоловіче. Ви, мабуть, заощадили мені багато часу. Багато! Дякую! Я щойно виконав sudo apt-get install ntpна моїй машині Debian встановлення NTP. Він синхронізував годинник, і проблема була вирішена.
Szymon Sadło

4

FYI: API Google Analytics 3.0 автоматично оновить маркер доступу, якщо у вас є маркер оновлення, коли термін його дії закінчується, тому ваш сценарій ніколи не потрібен refreshToken.

(Див. SignФункцію в auth/apiOAuth2.php)


"Автоматичне оновлення" означає, що мені просто потрібно попросити getAccessToken (), і я отримаю оновлений? Але я повинен спочатку встановити маркер оновлення з БД, так? В іншому випадку оновлення працювало б без токена оновлення, і я не думаю, що це могло б спрацювати
ninsky 01.03.18

4

Іноді Refresh Token i не генерується за допомогою $client->setAccessType ("offline");.

Спробуйте це:

$client->setAccessType ("offline");
$client->setApprovalPrompt ("force"); 

Якщо бути більш точним, схоже, маркер оновлення включений у вашу першу авторизацію. Якщо ви збережете, а потім використаєте його, я вважаю (на думку інших, не перевірено), що маркер оновлення продовжує повертатися. Доко також тепер каже, що вони автоматично оновлять маркер доступу, якщо у них є маркер оновлення, а це означає, що це просто питання надійного управління маркером оновлення. setApprovalPrompt ('force') примушує видавати маркер оновлення, який видається згодом; без нього ви не отримаєте іншого.
Brian C

2

Я використовував приклад за допомогою смарт-кодів з поточною версією Google API, але цей не працював. Я думаю, що його API занадто застарілий.

Отже, я щойно написав власну версію, засновану на одному з прикладів API ... Він видає маркер доступу, маркер запиту, тип маркера, маркер ідентифікатора, час закінчення та час створення у вигляді рядків

Якщо облікові дані вашого клієнта та ключ розробника правильні, цей код повинен працювати нестандартно.

<?php
// Call set_include_path() as needed to point to your client library.
require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_Oauth2Service.php';
session_start();

$client = new Google_Client();
$client->setApplicationName("Get Token");
// Visit https://code.google.com/apis/console?api=plus to generate your
// oauth2_client_id, oauth2_client_secret, and to register your oauth2_redirect_uri.
$oauth2 = new Google_Oauth2Service($client);

if (isset($_GET['code'])) {
    $client->authenticate($_GET['code']);
    $_SESSION['token'] = $client->getAccessToken();
    $redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
    header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
    return;
}

if (isset($_SESSION['token'])) {
    $client->setAccessToken($_SESSION['token']);
}

if (isset($_REQUEST['logout'])) {
    unset($_SESSION['token']);
    $client->revokeToken();
}
?>
<!doctype html>
<html>
    <head><meta charset="utf-8"></head>
    <body>
        <header><h1>Get Token</h1></header>
        <?php
        if ($client->getAccessToken()) {
            $_SESSION['token'] = $client->getAccessToken();
            $token = json_decode($_SESSION['token']);
            echo "Access Token = " . $token->access_token . '<br/>';
            echo "Refresh Token = " . $token->refresh_token . '<br/>';
            echo "Token type = " . $token->token_type . '<br/>';
            echo "Expires in = " . $token->expires_in . '<br/>';
            echo "ID Token = " . $token->id_token . '<br/>';
            echo "Created = " . $token->created . '<br/>';
            echo "<a class='logout' href='?logout'>Logout</a>";
        } else {
            $authUrl = $client->createAuthUrl();
            print "<a class='login' href='$authUrl'>Connect Me!</a>";
        }
        ?>
    </body>
</html>

1
Будь ласка, НЕ могли б ви пояснити мені , чому цей рядок: $redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];. Чому ви переспрямовуєте на ту саму сторінку? це необхідно?
Тропікаліста

@Tropicalista: Не потрібно перезавантажувати сторінку як таку, але саме таким чином зазвичай реалізуються потоки автентифікації.
John Slegers

але ви не використовуєте маркер оновлення, щоб отримати новий маркер доступу, якщо маркер доступу закінчився.
ападана

1

У мене така сама проблема з google / google-api-php-client v2.0.0-RC7, і після пошуку протягом 1 години я вирішив цю проблему за допомогою json_encode, як це:

    if ($client->isAccessTokenExpired()) {
        $newToken = json_decode(json_encode($client->getAccessToken()));
        $client->refreshToken($newToken->refresh_token);
        file_put_contents(storage_path('app/client_id.txt'), json_encode($client->getAccessToken()));
    }

1

Це тут працює дуже добре, можливо, це може допомогти кожному:

index.php

session_start();

require_once __DIR__.'/client.php';

if(!isset($obj->error) && isset($_SESSION['access_token']) && $_SESSION['access_token'] && isset($obj->expires_in)) {
?>
<!DOCTYPE html>
<html>
<head>
<title>Google API Token Test</title>
<meta charset='utf-8' />
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script>
search('Music Mix 2010');
function search(q) {
    $.ajax({
        type: 'GET',
        url: 'action.php?q='+q,
        success: function(data) {
            if(data == 'refresh') location.reload();
            else $('#response').html(JSON.stringify(JSON.parse(data)));
        }
    });
}
</script>
</head>
<body>
<div id="response"></div>
</body>
</html>
<?php
}
else header('Location: '.filter_var('https://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']).'/oauth2callback.php', FILTER_SANITIZE_URL));
?>

oauth2callback.php

require_once __DIR__.'/vendor/autoload.php';

session_start();

$client = new Google_Client();
$client->setAuthConfigFile('auth.json');
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
$client->setRedirectUri('https://'.filter_var($_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'], FILTER_SANITIZE_URL));
$client->addScope(Google_Service_YouTube::YOUTUBE_FORCE_SSL);

if(isset($_GET['code']) && $_GET['code']) {
    $client->authenticate(filter_var($_GET['code'], FILTER_SANITIZE_STRING));
    $_SESSION['access_token'] = $client->getAccessToken();
    $_SESSION['refresh_token'] = $_SESSION['access_token']['refresh_token'];
    setcookie('refresh_token', $_SESSION['refresh_token'], time()+60*60*24*180, '/', filter_var($_SERVER['HTTP_HOST'], FILTER_SANITIZE_URL), true, true);
    header('Location: '.filter_var('https://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']), FILTER_SANITIZE_URL));
    exit();
}
else header('Location: '.filter_var($client->createAuthUrl(), FILTER_SANITIZE_URL));
exit();

?>

client.php

// https://developers.google.com/api-client-library/php/start/installation
require_once __DIR__.'/vendor/autoload.php';

$client = new Google_Client();
$client->setAuthConfig('auth.json');
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
$client->addScope(Google_Service_YouTube::YOUTUBE_FORCE_SSL);

// Delete Cookie Token
#setcookie('refresh_token', @$_SESSION['refresh_token'], time()-1, '/', filter_var($_SERVER['HTTP_HOST'], FILTER_SANITIZE_URL), true, true);

// Delete Session Token
#unset($_SESSION['refresh_token']);

if(isset($_SESSION['refresh_token']) && $_SESSION['refresh_token']) {
    $client->refreshToken($_SESSION['refresh_token']);
    $_SESSION['access_token'] = $client->getAccessToken();
}
elseif(isset($_COOKIE['refresh_token']) && $_COOKIE['refresh_token']) {
    $client->refreshToken($_COOKIE['refresh_token']);
    $_SESSION['access_token'] = $client->getAccessToken();
}

$url = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token='.urlencode(@$_SESSION['access_token']['access_token']);
$curl_handle = curl_init();
curl_setopt($curl_handle, CURLOPT_URL, $url);
curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl_handle, CURLOPT_USERAGENT, 'Google API Token Test');
$json = curl_exec($curl_handle);
curl_close($curl_handle);

$obj = json_decode($json);

?>

action.php

session_start();

require_once __DIR__.'/client.php';

if(isset($obj->error)) {
    echo 'refresh';
    exit();
}
elseif(isset($_SESSION['access_token']) && $_SESSION['access_token'] && isset($obj->expires_in) && isset($_GET['q']) && !empty($_GET['q'])) {
    $client->setAccessToken($_SESSION['access_token']);
    $service = new Google_Service_YouTube($client);
    $response = $service->search->listSearch('snippet', array('q' => filter_input(INPUT_GET, 'q', FILTER_SANITIZE_SPECIAL_CHARS), 'maxResults' => '1', 'type' => 'video'));
    echo json_encode($response['modelData']);
    exit();
}
?>

1

Google вніс деякі зміни з моменту публікації цього питання.

Ось мій приклад, який зараз працює.

    public function update_token($token){

    try {

        $client = new Google_Client();
        $client->setAccessType("offline"); 
        $client->setAuthConfig(APPPATH . 'vendor' . DIRECTORY_SEPARATOR . 'google' . DIRECTORY_SEPARATOR . 'client_secrets.json');  
        $client->setIncludeGrantedScopes(true); 
        $client->addScope(Google_Service_Calendar::CALENDAR); 
        $client->setAccessToken($token);

        if ($client->isAccessTokenExpired()) {
            $refresh_token = $client->getRefreshToken();
            if(!empty($refresh_token)){
                $client->fetchAccessTokenWithRefreshToken($refresh_token);      
                $token = $client->getAccessToken();
                $token['refresh_token'] = json_decode($refresh_token);
                $token = json_encode($token);
            }
        }

        return $token;

    } catch (Exception $e) { 
        $error = json_decode($e->getMessage());
        if(isset($error->error->message)){
            log_message('error', $error->error->message);
        }
    }


}

1

Я використовую google-api-php-client v2.2.2. Я отримую новий маркер, fetchAccessTokenWithRefreshToken();якщо виклик функції без параметрів повертає оновлений маркер доступу, і оновлений маркер не втрачається.

if ($client->getAccessToken() && $client->isAccessTokenExpired()) {
    $new_token=$client->fetchAccessTokenWithRefreshToken();
    $token_data = $client->verifyIdToken();
}    

1

Вам потрібно зберегти маркер доступу до файлу або бази даних як рядок json під час первинного запиту авторизації та встановити тип доступу як офлайн $client->setAccessType("offline")

Потім, під час наступних запитів api, захопіть маркер доступу з вашого файлу або бази даних і передайте його клієнту:

$accessToken = json_decode($row['token'], true);
$client->setAccessToken($accessToken);

Тепер потрібно перевірити, чи термін дії маркера закінчився:

if ($client->isAccessTokenExpired()) {
    // access token has expired, use the refresh token to obtain a new one
    $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
    // save the new token to file or db
    // ...json_encode($client->getAccessToken())

fetchAccessTokenWithRefreshToken()Функція буде робити роботу за вас і надати новий маркер доступу, зберегти його назад в файл або базу даних.


0

Згідно з Authentication у google: OAuth2 продовжує повертати 'invalid_grant'

"Вам слід повторно використати маркер доступу, який ви отримаєте після першої успішної автентифікації. Ви отримаєте помилку invalid_grant, якщо ваш попередній маркер ще не закінчився. Зберігайте його десь, щоб ви могли повторно використовувати його."

сподіваюся, це допоможе


-1

використовуйте наступний фрагмент коду, щоб отримати маркер оновлення

    <?php

    require_once 'src/apiClient.php';
    require_once 'src/contrib/apiTasksService.php';

    $client = new apiClient();
    $client->setAccessType('offline');
    $tasksService = new apiTasksService($client);

    $auth = $client->authenticate();
    $token = $client->getAccessToken();
    // the refresh token
    $refresh_token = $token['refresh_token'];
    ?>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.