OAuth2 token,消息:'{"error":“;access_denied"


OAuth2 token, message: '{ "error" : "access_denied" }' returned when I try to update Google Calendar using OAuth (Service Account)

我使用谷歌标准库PHP使用日历服务,我已经通过谷歌API控制台设置了OAuth 2.0认证的服务帐户类型。

我的主要目标是更新用户的谷歌日历(例如:user@organisationname.com)(当用户不在线时)通过批处理。如。更新用户日历中的事件。

当用户登录应用程序(使用OAuth2.0)时,他/她将为应用程序提供"管理您的日历","查看您的日历"answers"在我不使用应用程序时执行这些操作"的权限

以下代码用于使用OAuth2.0

登录
<?php
require_once '../../src/Google_Client.php';
require_once '../../src/contrib/Google_CalendarService.php';
session_start();
$client = new Google_Client();
$client->setApplicationName("Google Calendar PHP Starter Application");

$client->setClientId('XXXXX-flue2a9o5ll602ovrhaejlpm9otgjh1r.apps.googleusercontent.com');
$client->setClientSecret('XXXXXXXXXX');
$client->setRedirectUri('http://localhost/testAPI/google-api-php-client/examples/calendar/simple.php');
$client->setDeveloperKey('AIzaSyCGvXRXGMo58ZDswyb4zBkJgRMLcHBRIrI');
$cal = new Google_CalendarService($client);
if (isset($_GET['logout'])) {
  unset($_SESSION['token']);
}
if (isset($_GET['code'])) {
  $client->authenticate($_GET['code']);
  $_SESSION['code']=$_GET['code'];
  $_SESSION['token'] = $client->getAccessToken();
  header('Location: http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']);
}
if (isset($_SESSION['token'])) {
  $client->setAccessToken($_SESSION['token']);
}
if ($client->getAccessToken()) {
  $calList = $cal->calendarList->listCalendarList();
  print "<h1>Calendar List</h1><pre>" . print_r($calList, true) . "</pre>";
  echo $_SESSION['code'];

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

一旦我获得权限,我是否必须保存一些东西以便在将来用户未登录时使用这些权限?

当用户登录时,以下代码可以正常工作。但是返回刷新OAuth2令牌错误,消息:'{" Error ": "access_denied"}'当用户注销

<?php 
require_once '../src/Google_Client.php';
require_once '../src/contrib/Google_CalendarService.php';
session_start();
const CLIENT_ID = 'XXXXXX.apps.googleusercontent.com';
const SERVICE_ACCOUNT_NAME = 'XXXX@developer.gserviceaccount.com';
const KEY_FILE = 'f183b8caXXXXXXXXatekey.p12';
$client = new Google_Client();
$client->setApplicationName("XXXXXXXX Calendar Service");
if (isset($_SESSION['token'])) {
 $client->setAccessToken($_SESSION['token']);
}
$key = file_get_contents(KEY_FILE);
$client->setClientId(CLIENT_ID);
$client->setAssertionCredentials(new Google_AssertionCredentials(
        SERVICE_ACCOUNT_NAME,
        array('https://www.googleapis.com/auth/calendar'),
        $key,
        'notasecret',
        'http://oauth.net/grant_type/jwt/1.0/bearer',
        '363183053@developer.gserviceaccount.com')
);
$client->setClientId(CLIENT_ID);
$cal = new Google_CalendarService($client);
    try{
$cal->events->quickAdd("info@organisationname.com", "SERVICE TEST ");
}catch(Exception $e){
    print_r($e->getMessage());
}
// We're not done yet. Remember to update the cached access token.
// Remember to replace $_SESSION with a real database or memcached.
if ($client->getAccessToken()) {
    echo $_SESSION['token'] = $client->getAccessToken();
}

当用户没有登录时,我应该怎么做才能更新日历(提供用户已给予许可)。当用户登录并在以后想要运行批处理时使用时,我应该保存访问码吗?

BTW什么是关联句柄?

实际上您不需要与服务帐户共享日历。需要做的是将域范围内的权限委托给您的服务帐户。

您现在创建的服务帐户需要被授予对您想要访问的Google Apps域用户数据的访问权限。

以下任务必须由Google Apps域的管理员执行:1. 进入你的Google Apps域的控制面板。URL应该看起来像:https://www.google.com/a/cpanel/mydomain.com

  1. 进入高级工具…>管理第三方OAuth客户端访问

  2. 在Client name字段中输入服务帐户的Client ID。

  3. 在"一个或多个API范围"字段中输入应用程序应该被授予访问权限的范围列表。例如,如果您需要对Google Calendar API进行全域只读访问,请输入:https://www.googleapis.com/auth/calendar.readonly

  4. 点击授权按钮

你得到的错误,因为你的范围没有正确提到。在Google OAuth 2.0中定义的Scope:

表示应用程序正在请求的Google API访问。的在此参数中传递的值通知显示的同意页用户。的数量成反比请求的权限和获得用户同意的可能性。

以空格分隔的应用程序请求的权限集

  • 要解决这个问题,你必须首先改变范围参数

  • 包含日历范围

  • 然后获取访问令牌,然后尝试更改

  • 然后根据API文档

  • 中提供的要求和步骤进行相应的更改