【问题标题】:Fatal error: Uncaught exception 'Google_Auth_Exception' with message 'Error refreshing the OAuth2 token, message: '{ "error" : "invalid_grant" }致命错误:未捕获的异常“Google_Auth_Exception”带有消息“刷新 OAuth2 令牌时出错,消息:'{“error”:“invalid_grant”}
【发布时间】:2014-08-19 06:17:34
【问题描述】:

我有一个基于最新版 Google-api-php 客户端版本 1.0.0 的预测应用程序。它在 localhost 环境中完美运行。但是当我将相同的应用程序部署到托管服务器环境中时,它给了我以下问题。

这是我从宿主环境中得到的错误

Fatal error: Uncaught exception 'Google_Auth_Exception' with message 'Error refreshing the OAuth2 token, message: '{ "error" : "invalid_grant" }'' in /home/predict/public_html/predict/Google/Auth/OAuth2.php:335 Stack trace: #0 /home/predict/public_html/predict/Google/Auth/OAuth2.php(294): Google_Auth_OAuth2->refreshTokenRequest(Array) #1 /home/predict/public_html/predict/index.php(40): Google_Auth_OAuth2->refreshTokenWithAssertion(Object(Google_Auth_AssertionCredentials)) #2 {main} thrown in /home/predict/public_html/predict/Google/Auth/OAuth2.php on line 335

*CURL 和 JSON 扩展在 Hosting 环境下正常工作。

这是我的完整源代码

<?php
session_start();

set_include_path("Google" . PATH_SEPARATOR . get_include_path());
require_once 'Client.php';
require_once 'Service/Prediction.php';

$client_id              = 'XXXXXXXXXX-uin70k09g5g6f05vqvdj9ch541c4spns.apps.googleusercontent.com';    
$service_account_name   = 'XXXXXXXXXX-uin70k09g5g6f05vqvdj9ch541c4spns@developer.gserviceaccount.com';  
$key_file_location      = 'APPKEY-d333c55a111a.p12';

if ($client_id == 'XXXXXXXXXX-uin70k09g5g6f05vqvdj9ch541c4spns.googleusercontent.com'
    || !strlen($service_account_name)
    || !strlen($key_file_location)) {  
}

$client = new Google_Client();

$client->setApplicationName("Predition App");
$service = new Google_Service_Prediction($client);

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

$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
    $service_account_name,`enter code here`
    array('https://www.googleapis.com/auth/prediction'),
    $key
);

$client->setAssertionCredentials($cred);

if($client->getAuth()->isAccessTokenExpired()) {    
  $client->getAuth()->refreshTokenWithAssertion($cred); 
}

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

// Prediction logic:
$id             = 'datamodel';
$project        = "XXXXXXXXXX";

$input          = $_REQUEST['input'];

//$predictionData = new Google_InputInput();  //Depricated method in Google_api_php_client_version1.0.0      // W.P.Roshan
$predictionData = new Google_Service_Prediction_InputInput();
$predictionData->setCsvInstance(array($input));

//$input = new Google_Input();                //Depricated method in Google_api_php_client_version1.0.0 // W.P.Roshan
$input = new Google_Service_Prediction_Input();
$input->setInput($predictionData);

$PredictionResult = $service->trainedmodels->predict($project,$id, $input,$optParams = array());
//print '<h3>Prediction Result:</h3><pre>' . print_r($result, true) . '</pre>';

$AccuracyMetaResult = $service->trainedmodels->get($project, $id, $optParams = array());    
//print '<h3>Classification Accuracy Result:</h3><pre>' . print_r($result, true) . '</pre>';

$stdout                     = new stdClass();
$stdout->dataModel          = $PredictionResult['id'];
$stdout->outputLabel        = $PredictionResult['outputLabel'];
$stdout->negative           = $PredictionResult['modelData']['outputMulti'][0]['score'];
$stdout->neutral            = $PredictionResult['modelData']['outputMulti'][1]['score'];
$stdout->positive           = $PredictionResult['modelData']['outputMulti'][2]['score'];
$stdout->modelCreated       = $AccuracyMetaResult['created'];
$stdout->trainingCompleted  = $AccuracyMetaResult['trainingComplete'];
$stdout->trainingStatus     = $AccuracyMetaResult['trainingStatus'];
$stdout->modelType          = $AccuracyMetaResult['modelData']['modelInfo']['modelType'];
$stdout->dataModelAccuracy  = $AccuracyMetaResult['modelData']['modelInfo']['classificationAccuracy'];

echo json_encode($stdout);

if ($client->getAccessToken()) {
  $_SESSION['token'] = $client->getAccessToken();
} 

【问题讨论】:

  • 如果您的主机 WHM/CPanel 要求他们将服务器时间与时间服务器(ntp.org - 如果您的主机使用 NTP - 网络时间协议)同步 如果您的主机在 Virtuozzo VPS 上,请要求主机人同步带时间服务器的 VPS。 @DalmTo - 没有你的支持,这将不会得到解决,非常感谢 DalmTo。

标签: google-api-php-client service-accounts google-prediction


【解决方案1】:

我花了几个小时试图解决这个问题。结果我的服务器时间比谷歌的时间早了几分钟。

将我的服务器时间设置为正确的时间立即解决了这个问题。

希望这可以帮助某人:)

【讨论】:

  • 能否详细说明。我也在我的 linux 机器上安装了 ntp,但无法理解如何解决这个问题。我还将我的位置时间设置为亚洲/加尔各答。
【解决方案2】:

我认为你做事的顺序有问题。在获得身份验证之前,您正在创建服务。这是一个使用 google analytics api 的示例。

<?php
session_start();
require_once 'Google/Client.php';
require_once 'Google/Service/Analytics.php';

/************************************************
  The following 3 values an befound in the setting
  for the application you created on  Google 
  Developers console.
  The Key file should be placed in a location
  that is not accessable from the web. outside of 
  web root.

  In order to access your GA account you must
  Add the Email address as a user at the 
  ACCOUNT Level in the GA admin. 
 ************************************************/
$client_id = '1046123799103-nk421gjc2v8mlr2qnmmqaak04ntb1dbp.apps.googleusercontent.com';
$Email_address = '1046123799103-nk421gjc2v8mlr2qnmmqaak04ntb1dbp@developer.gserviceaccount.com';
$key_file_location = '629751513db09cd21a941399389f33e5abd633c9-privatekey.p12';

$client = new Google_Client();
$client->setApplicationName("Client_Library_Examples");

$key = file_get_contents($key_file_location);

// seproate additional scopes with a comma
$scopes ="https://www.googleapis.com/auth/analytics.readonly";  

$cred = new Google_Auth_AssertionCredentials(
    $Email_address,
    array($scopes),
    $key
    );

$client->setAssertionCredentials($cred);
if($client->getAuth()->isAccessTokenExpired()) {
    $client->getAuth()->refreshTokenWithAssertion($cred);
}

$service = new Google_Service_Analytics($client);  
$accounts = $service->management_accountSummaries->listManagementAccountSummaries();

//calulating start date
$date = new DateTime(date("Y-m-d"));
$date->sub(new DateInterval('P10D'));

//Adding Dimensions
$params = array('dimensions' => 'ga:userType');
// requesting the data
$data = $service->data_ga->get("ga:78110423", $date->format('Y-m-d'),  date("Y-m-d"), "ga:users,ga:sessions", $params );


?><html>
<?php echo $date->format('Y-m-d') . " - ".date("Y-m-d"). "\n";?>
<table>
<tr>
<?php
//Printing column headers
foreach($data->getColumnHeaders() as $header){  
    print "<td>".$header['name']."</td>";   
}
?>
</tr>
<?php
//printing each row.
foreach ($data->getRows() as $row) {    
    print "<tr><td>".$row[0]."</td><td>".$row[1]."</td><td>".$row[2]."</td></tr>";  
}

//printing the total number of rows
?>
<tr><td colspan="2">Rows Returned <?php print $data->getTotalResults();?> </td></tr>
</table>
</html>
<?php

?>

示例取自我的教程Google Service Account php

【讨论】:

  • @DalmTo - 如果我在获得身份验证之前创建服务,那么为什么它在 localhost 环境中正常工作。
  • Google_Auth_AssertionCredentials 需要首先创建,因为它被发送到 $client 然后使用具有其身份验证的 $client 创建服务。你在倒退
  • 如果我向后做,为什么它在 localhost 环境下工作。这似乎不是问题,伙计..但是很好的尝试...谢谢。
  • 选项 nr 2:检查服务器时钟,确保设置正确。它需要与 NTP 同步。如果不是,它认为您的身份验证有问题,您将获得 invalid_grant。
  • 是的,这是一种可以接受的答案,但 NTP 是什么?以及如何与我的托管服务器时间同步。
【解决方案3】:

我在登录页面时遇到了同样的错误。 由于重新认证而出现此错误。

一旦您成功登录到您的页面。在您的代码中检查是否设置了 Session。否则它将再次验证用户。这就是我解决错误的方法。希望它也对你有用。

if(isset($_GET['code'])){<br>
     if(!isset($_SESSION['token'])){
        $gClient->authenticate($_GET['code']);
        $_SESSION['token'] = $gClient->getAccessToken();
    header('location:'.filter_var($redirectURL,FILTER_SANITIZE_URL));
    }
}

【讨论】:

    猜你喜欢
    • 2014-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多