3

我需要制作一个 PHP 脚本,在 Google 日历上创建一个单一事件。我在设置客户端 ID、客户端密码、开发密钥和创建新事件时没有问题。

我唯一的问题是 OAuth2,特别是我需要建立永久连接,并且我不想每次运行脚本时都进行身份验证。

实际上,使用这个脚本,我可以获得一个令牌和一个刷新令牌,但是我的令牌每小时都会过期,我不知道如何刷新它。我该如何编辑此代码来做到这一点?我可以将令牌和刷新令牌都保存在某处并始终使用相同的数据吗?

我获得了一个未捕获的异常“Google_AuthException”,并带有消息“刷新 OAuth2 令牌时出错,消息:'{“error”:“invalid_grant”

我已经在 stackoverflow 中阅读了有关此主题的其他一些帖子,但我仍然没有找到解决方案...:\

<?php

 require_once 'src/Google_Client.php';
 require_once 'src/contrib/Google_CalendarService.php';
 session_start();

 $client = new Google_Client();
 $client->setApplicationName("Calendar App");
 $client->setClientId('xxxx');
 $client->setClientSecret('yyy');
 $client->setRedirectUri('http://www.zzzzzz');  
 $client->setDeveloperKey('kkk');
 $client->setAccessType('offline');
 $cal = new Google_CalendarService($client);    

if (isset($_GET['logout'])) {
  unset($_SESSION['token']);
}

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

if (isset($_SESSION['token'])) {
    //echo $_SESSION['token'];
  //$client->setAccessToken($_SESSION['token']);
    $authObj = json_decode($_SESSION['token']);
    $accessToken = $authObj->access_token;
    $refreshToken = $authObj->refresh_token;
    $tokenType = $authObj->token_type;
    $expiresIn = $authObj->expires_in;
    echo 'access_token = ' . $accessToken;
    echo '<br />';
    echo 'refresh_token = ' . $refreshToken;
    echo '<br />';
    echo 'token_type = ' . $tokenType;
    echo '<br />';
    echo 'expires_in = ' . $expiresIn;
}

if(!empty($cookie)){
    $client->refreshToken($this->Cookie->read('token'));
}

if ($client->getAccessToken()) {
    $calList = $cal->calendarList->listCalendarList();
    $_SESSION['token'] = $client->getAccessToken();
} else {
  $authUrl = $client->createAuthUrl();
  print "<a class='login' href='$authUrl'>Connect Me!</a>";
}


// Creation of a single event
$event = new Google_Event();
$event->setSummary($event_name);            
$event->setLocation('');                    
....

?>

多谢您的支持!

4

3 回答 3

5

此页面https://developers.google.com/accounts/docs/OAuth2WebServer#offline解释了刷新令牌的工作原理,以及如何使用它通过原始 http 获取新的访问令牌。

从这个问题How to refresh token with Google API client? 这是 php 等价物

here is the snippet to set token, before that make sure the access type should be set to offline

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

$google_token= json_decode($_SESSION['access_token']);
$client->refreshToken($google_token->refresh_token);
this will refresh your token, you have to update it in session for that you can do

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

调试 按照以下三个步骤调试任何 oauth 应用程序

  1. 确保您已阅读https://developers.google.com/accounts/docs/OAuth2以及相应的子页面(webapp、javascript 等),具体取决于您使用的 oauth 风格。如果您不了解应用程序在做什么,那么您将无法调试您的应用程序。

  2. 使用https://developers.google.com/oauthplayground/上的 Oauth Playground 完成 Oauth 步骤并最终进行 Google API 调用。这将确认您的理解并向您展示 http 调用和响应的样子

  3. 使用 tracking/logging/proxy 等来跟踪来自您的应用程序的实际 http 流量。将此与您在第 2 步中观察到的情况进行比较。这应该会告诉您问题出在哪里。

于 2013-11-08T06:32:16.597 回答
2

我之前收到此错误是因为我尝试进行两次身份验证。

既然你有这条线:

if (isset($_GET['code']))

当代码在查询字符串中时,无论您是否已经通过身份验证,它都会尝试进行身份验证。在尝试(重新)身份验证之前尝试检查 SESSION 令牌是否存在。

于 2013-12-09T23:45:46.273 回答
0

尝试删除 setDeveloperKey(),这对我造成了一些问题,而且似乎不需要。

于 2014-06-18T23:58:22.900 回答