Oauth 2.0 Gmail API返回403错误代码和;由于<;用户电子邮件>&引用;

Oauth 2.0 Gmail API返回403错误代码和;由于<;用户电子邮件>&引用;,oauth-2.0,google-oauth,gmail-api,google-api-php-client,Oauth 2.0,Google Oauth,Gmail Api,Google Api Php Client,检索带有以下错误的邮件时,一个域的Gmail API失败: com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 OK { "code" : 403, "errors" : [ { "domain" : "global", "message" : "Delegation denied for <user email>", "reason" : "forbidden"

检索带有以下错误的邮件时,一个域的Gmail API失败:

com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 OK
{
  "code" : 403,
  "errors" : [ {
    "domain" : "global",
    "message" : "Delegation denied for <user email>",
    "reason" : "forbidden"
  } ],
  "message" : "Delegation denied for <user email>"
}
com.google.api.client.googleapis.json.GoogleJsonResponseException:403 OK
{
“代码”:403,
“错误”:[{
“域”:“全局”,
“消息”:“拒绝的授权”,
“原因”:“禁止”
} ],
“消息”:“拒绝的委派”
}

我正在使用OAuth 2.0和Google Apps域范围的授权访问用户数据。域已授予应用程序的数据访问权限。

似乎最好的做法是在您的请求中始终包含userId=“me”。这告诉API只使用经过身份验证的用户的邮箱——不需要依赖电子邮件地址。

我们的用户已迁移到域中,并且他们的帐户已附加别名。我们需要将SendAs地址默认为一个导入的别名,并希望找到一种自动化它的方法。Gmail API看起来像是解决方案,但我们的特权用户(具有对帐户进行更改的角色)不起作用——我们一直看到“Delegation denied for”403错误

下面是一个PHP示例,说明我们如何列出他们的SendAs设置

<?PHP

//
// Description:
//   List the user's SendAs addresses.
//
// Documentation:
//   https://developers.google.com/gmail/api/v1/reference/users/settings/sendAs
//   https://developers.google.com/gmail/api/v1/reference/users/settings/sendAs/list
//
// Local Path:
//   /path/to/api/vendor/google/apiclient-services/src/Google/Service/Gmail.php
//   /path/to/api/vendor/google/apiclient-services/src/Google/Service/Gmail/Resource/UsersSettingsSendAs.php
//
// Version:
//    Google_Client::LIBVER  == 2.1.1
//

require_once $API_PATH . '/path/to/google-api-php-client/vendor/autoload.php';

date_default_timezone_set('America/Los_Angeles');

// this is the service account json file used to make api calls within our domain
$serviceAccount = '/path/to/service-account-with-domain-wide-delagation.json';
putenv('GOOGLE_APPLICATION_CREDENTIALS=' . $serviceAccount );

$userKey = 'someuser@my.domain';

// In the Admin Directory API, we may do things like create accounts with 
// an account having roles to make changes. With the Gmail API, we cannot 
// use those accounts to make changes. Instead, we impersonate
// the user to manage their account.

$impersonateUser = $userKey;

// these are the scope(s) used.
define('SCOPES', implode(' ', array( Google_Service_Gmail::GMAIL_SETTINGS_BASIC ) ) );

$client = new Google_Client();
$client->useApplicationDefaultCredentials();  // loads whats in that json service account file.
$client->setScopes(SCOPES); // adds the scopes
$client->setSubject($impersonateUser);  // account authorized to perform operation

$gmailObj  = new Google_Service_Gmail($client);

$res       = $gmailObj->users_settings_sendAs->listUsersSettingsSendAs($userKey);

print_r($res);


?>

我想访问新电子邮件id/帐户的电子邮件,但实际情况是,最近创建的包含JSON的“.credentials”文件夹与我先前尝试的电子邮件id/帐户相关联。JSON中存在的访问令牌和其他参数与新的电子邮件id/帐户不关联。因此,为了让它运行,您只需删除“.credentails”文件夹,然后再次运行该程序。现在,程序打开浏览器并要求您授予权限

删除包含python文件的文件夹的步骤

import shutil
shutil.rmtree("path of the folder to be deleted")

您可以在程序末尾添加此选项,我以前也遇到过同样的问题,解决方案非常复杂,您需要先模拟需要访问gmail内容的人,然后使用userId='me'运行查询。它对我有用

以下是一些示例代码:

   users = # coming from directory service
   for user in users:
     credentials = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)
     ####IMPORTANT######
     credentials_delegated = credentials.with_subject(user['primaryEmail'])

     gmail_service = build('gmail', 'v1', credentials=credentials_delegated)

     results = gmail_service.users().labels().list(userId='me').execute()
     labels = results.get('labels', [])
       for label in labels:
          print(label['name'])

最近,我开始探索Gmail API,我遵循郭提到的方法。然而,当我们计算用户数或更多时,这将需要时间和太多的呼叫。在域范围内委派之后,我的期望是管理员id将能够访问委派的收件箱,但似乎我们需要为每个用户创建服务。

我们也开始出现此错误。迄今为止没有任何问题。如果我们使用IMAP,一切都很好——看起来Gmail API有点问题。谷歌帮助??它以前有用吗?还是刚刚坏了?如果它刚刚坏了,你能给出它坏的时间吗?如果它从未工作过,您能否确认它是一个服务帐户,在Cpanel中被列为白名单,并提供关于域范围设置的更多详细信息?您使用的是:I imagine?您是否也可以发布您在请求中对“userId”字段使用的值?是“我”吗?用户的电子邮件地址应与身份验证令牌或其他内容匹配?只有在使用与授权用户不同的userId参数时,才会发生此错误。这种授权方式不受支持。正确的方法是在获取访问令牌时模拟用户,并坚持使用“me”作为userId。在调用Gmail API时只需使用:userId=“me”。对于具有域范围授权的服务帐户,在请求访问令牌时,您指定电子邮件地址的唯一时间是“sub”参数。我已将代码更改为使用“我”而不是实际的电子邮件地址。问题是由于电子邮件地址是我实例中的别名而导致的。将电子邮件地址更改为“我”也对我有效。谢谢。@USER133358您应该接受这个答案-我为此挣扎了两个小时。就是这样!太神了已经寻找了这么久,有了这个简单的解决方案。这就是答案吗?还是评论?请仅在答案部分发布答案。