Почему я продолжаю ловить Google_Auth_Exception для invalid_grant?

Я пытаюсь создать веб-приложение, которое обращается к API Google Analytics и извлекает данные. Однако у меня есть некоторые проблемы с авторизацией OAuth 2.0.

Он позволяет успешно получить начальный доступ, но он быстро выкидывает меня и бросает сообщение Google_Auth_Exception с сообщением «Ошибка получения маркера доступа OAuth2, сообщение:« invalid_grant », когда я нажимаю кнопку отправки, которая обновляет страницу.

Насколько я понимаю OAuth 2.0, для аутентификации существует 4 шага:

  1. Получить учетные данные OAuth 2.0 с помощью Google Dev Console
  2. Получить токен доступа с сервера авторизации Google
  3. Отправлять токен доступа в API Google Analytics
  4. Обновите токен доступа, если необходимо

И, как я понимаю, $ client-> setAccessToken (); автоматически обновляет токен.

Я не могу найти какую-либо документацию от Google, так как они переехали в Github, и я по большей части следил за их структурами.

Ошибка выдается из первого блока try, когда он пытается выполнить $ client-> authenticate ($ _ GET ['code']);

Моим текущим обходным решением является снятие токена сеанса и повторная авторизация пользователя. Однако это действительно громоздко и навязчиво, так как любое взаимодействие со страницей потребует повторной авторизации.

Любая помощь будет принята с благодарностью!

Вот мой код:

<?php /********************** OAUTH 2.0 AUTHORIZATION ***********************/ //required libraries set_include_path("../src/" . PATH_SEPARATOR . get_include_path()); require_once 'Google/Client.php'; require_once 'Google/Service/Analytics.php'; //variables $client_id = 'redacted'; $client_secret = 'redacted'; $redirect_uri = 'http://'.$_SERVER["HTTP_HOST"].$_SERVER['PHP_SELF']; $dev_key = 'redacted'; //create a Google client $client = new Google_Client(); $client->setApplicationName('App'); //sets client's API information $client->setClientId($client_id); $client->setClientSecret($client_secret); $client->setRedirectUri($redirect_uri); $client->setDeveloperKey($dev_key); $client->setScopes(array('https://www.googleapis.com/auth/analytics.readonly')); //if log out is requested, revoke the access if (isset($_REQUEST['logout'])) { unset($_SESSION['token']); } //check if authorization code is in the URL try{ if (isset($_GET['code'])) { $client->authenticate($_GET['code']); //does authorization work $_SESSION['access_token'] = $client->getAccessToken(); //gets valid access token $redirect = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']; //set into session storage header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL)); //cleans up the URL } } //if the authorization code is now invalid catch (Google_Auth_Exception $e) { unset($_SESSION['token']); //unset the session token echo "Token now invalid, please revalidate. <br>"; } //if there is an access token in the session storage if (isset($_SESSION['access_token']) && $_SESSION['access_token']) { $client->setAccessToken($_SESSION['access_token']); //set the client's access token //try creating an analytics object try { $analytics = new Google_Service_Analytics($client); echo 'Created Google Analytics Client successfully! <br><br>'; } catch (Google_Auth_Exception $e) { echo 'Need authorization!'; } } else { $authUrl = $client->createAuthUrl(); //create one echo "<a class='login' href='$authUrl'><button>Authorize Google Access</button></a>"; //print button } 

Я решил проблему. Я пытался дважды авторизовать один и тот же код аутентификации, и поэтому он возвратил ошибку invalid_grant .

Моим решением было переписать большую часть кода и исправить логику OAuth2.

Я создал мини-учебник потока аутентификации OAuth2 ниже:

 <?php session_start(); // Create a session /************************** * Google Client Configuration * * You may want to consider a modular approach, * and do the following in a separate PHP file. ***************************/ /* Required Google libraries */ require_once 'Google/Client.php'; require_once 'Google/Service/Analytics.php'; /* API client information */ $clientId = 'YOUR-CLIENT-ID-HERE'; $clientSecret = 'YOUR-CLIENT-SECRET-HERE'; $redirectUri = 'http://www.example.com/'; $devKey = 'YOUR-DEVELOPER-KEY-HERE'; // Create a Google Client. $client = new Google_Client(); $client->setApplicationName('App'); // Set your app name here /* Configure the Google Client with your API information */ // Set Client ID and Secret. $client->setClientId($clientId); $client->setClientSecret($clientSecret); // Set Redirect URL here - this should match the one you supplied. $client->setRedirectUri($redirectUri); // Set Developer Key and your Application Scopes. $client->setDeveloperKey($devKey); $client->setScopes( array('https://www.googleapis.com/auth/analytics.readonly') ); /************************** * OAuth2 Authentication Flow * * You may want to consider a modular approach, * and do the following in a separate PHP file. ***************************/ // Create a Google Analytics Service using the configured Google Client. $analytics = new Google_Service_Analytics($client); // Check if there is a logout request in the URL. if (isset($_REQUEST['logout'])) { // Clear the access token from the session storage. unset($_SESSION['access_token']); } // Check if there is an authentication code in the URL. // The authentication code is appended to the URL after // the user is successfully redirected from authentication. if (isset($_GET['code'])) { // Exchange the authentication code with the Google Client. $client->authenticate($_GET['code']); // Retrieve the access token from the Google Client. // In this example, we are storing the access token in // the session storage - you may want to use a database instead. $_SESSION['access_token'] = $client->getAccessToken(); // Once the access token is retrieved, you no longer need the // authorization code in the URL. Redirect the user to a clean URL. header('Location: '.filter_var($redirectUri, FILTER_SANITIZE_URL)); } // If an access token exists in the session storage, you may use it // to authenticate the Google Client for authorized usage. if (isset($_SESSION['access_token']) && $_SESSION['access_token']) { $client->setAccessToken($_SESSION['access_token']); } // If the Google Client does not have an authenticated access token, // have the user go through the OAuth2 authentication flow. if (!$client->getAccessToken()) { // Get the OAuth2 authentication URL. $authUrl = $client->createAuthUrl(); /* Have the user access the URL and authenticate here */ // Display the authentication URL here. } /************************** * OAuth2 Authentication Complete * * Insert your API calls here ***************************/ с <?php session_start(); // Create a session /************************** * Google Client Configuration * * You may want to consider a modular approach, * and do the following in a separate PHP file. ***************************/ /* Required Google libraries */ require_once 'Google/Client.php'; require_once 'Google/Service/Analytics.php'; /* API client information */ $clientId = 'YOUR-CLIENT-ID-HERE'; $clientSecret = 'YOUR-CLIENT-SECRET-HERE'; $redirectUri = 'http://www.example.com/'; $devKey = 'YOUR-DEVELOPER-KEY-HERE'; // Create a Google Client. $client = new Google_Client(); $client->setApplicationName('App'); // Set your app name here /* Configure the Google Client with your API information */ // Set Client ID and Secret. $client->setClientId($clientId); $client->setClientSecret($clientSecret); // Set Redirect URL here - this should match the one you supplied. $client->setRedirectUri($redirectUri); // Set Developer Key and your Application Scopes. $client->setDeveloperKey($devKey); $client->setScopes( array('https://www.googleapis.com/auth/analytics.readonly') ); /************************** * OAuth2 Authentication Flow * * You may want to consider a modular approach, * and do the following in a separate PHP file. ***************************/ // Create a Google Analytics Service using the configured Google Client. $analytics = new Google_Service_Analytics($client); // Check if there is a logout request in the URL. if (isset($_REQUEST['logout'])) { // Clear the access token from the session storage. unset($_SESSION['access_token']); } // Check if there is an authentication code in the URL. // The authentication code is appended to the URL after // the user is successfully redirected from authentication. if (isset($_GET['code'])) { // Exchange the authentication code with the Google Client. $client->authenticate($_GET['code']); // Retrieve the access token from the Google Client. // In this example, we are storing the access token in // the session storage - you may want to use a database instead. $_SESSION['access_token'] = $client->getAccessToken(); // Once the access token is retrieved, you no longer need the // authorization code in the URL. Redirect the user to a clean URL. header('Location: '.filter_var($redirectUri, FILTER_SANITIZE_URL)); } // If an access token exists in the session storage, you may use it // to authenticate the Google Client for authorized usage. if (isset($_SESSION['access_token']) && $_SESSION['access_token']) { $client->setAccessToken($_SESSION['access_token']); } // If the Google Client does not have an authenticated access token, // have the user go through the OAuth2 authentication flow. if (!$client->getAccessToken()) { // Get the OAuth2 authentication URL. $authUrl = $client->createAuthUrl(); /* Have the user access the URL and authenticate here */ // Display the authentication URL here. } /************************** * OAuth2 Authentication Complete * * Insert your API calls here ***************************/ 

Надеюсь, это поможет кому-то застрять в будущем!

в моем случае это была проблема повторной аутентификации. Я тестировал api и получил код. Чтобы получить токен доступа, мне пришлось отменить доступ из раздела section-> security-> apps. Теперь выберите имя приложения и удалите его. теперь попробуйте, и вы получите ответный токен.

Ошибка: Uncaught exception «Google_Auth_Exception» с сообщением «Ошибка получения маркера доступа OAuth2, сообщение:« invalid_grant: код уже был выкуплен

После добавления

 header('Location: '.filter_var($redirectUri, FILTER_SANITIZE_URL)); 

Я получил сообщение об ошибке Invalid Request Parameter . Как его решить?