Як оновити маркер за допомогою клієнта 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.