Gmail API 返回 403 错误代码和“<user email> 的委托被拒绝”
Posted
技术标签:
【中文标题】Gmail API 返回 403 错误代码和“<user email> 的委托被拒绝”【英文标题】:Gmail API returns 403 error code and "Delegation denied for <user email>" 【发布时间】:2014-11-25 22:28:09 【问题描述】:在检索出现此错误的邮件时,一个域的 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>"
我正在使用 OAuth 2.0 和 Google Apps 域范围授权来访问用户数据。域已授予应用程序的数据访问权限。
【问题讨论】:
我们也开始出现此错误。迄今为止没有任何问题。如果我们使用 IMAP 一切都很好 - 看起来 Gmail API 有一些问题。谷歌帮助?? 这之前是否有效或刚刚中断?如果它刚刚坏了,你能给出它坏的时间吗?如果它从未起作用,您能否确认它是一个服务帐户,在 Cpanel 中列入白名单并提供有关域范围设置的更多详细信息?您正在使用类似:developers.google.com/accounts/docs/… 我想? 您还可以发布您在请求中为“userId”字段使用的值吗?是“我”,应该与身份验证令牌匹配的用户电子邮件地址还是其他? 只有当您使用不同于授权用户的 userId 参数时才会出现该错误。不支持这种委托方式。正确的方法是在获取访问令牌时冒充用户并坚持使用'me'作为userId。 只需在调用 Gmail API 时使用:userId="me"。对于具有域范围委派的服务帐户,您指定电子邮件地址的唯一时间是在请求访问令牌时用于“sub”参数。 【参考方案1】:似乎最好的办法就是在您的请求中始终包含 userId="me" 。这告诉 API 只使用经过身份验证的用户的邮箱——无需依赖电子邮件地址。
【讨论】:
我将代码更改为使用“我”而不是实际的电子邮件地址。问题是由于电子邮件地址在我的实例中是别名造成的。 将电子邮件地址更改为“我”也对我有用。谢谢。 @user1333358 你应该接受答案 - 它有效 我为此苦苦挣扎了两个小时。就是这个! 太棒了!找了这么久,有了这个简单的解决方案。【参考方案2】:我们的用户已迁移到某个域,并且他们的帐户附加了别名。我们需要将 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);
?>
【讨论】:
【参考方案3】:我之前也遇到过同样的问题,解决方案非常棘手,您需要先冒充您需要访问 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'])
【讨论】:
【参考方案4】:我想访问新电子邮件 ID/帐户的电子邮件,但发生的情况是,最近创建的包含 JSON 的“.credentials”文件夹与我之前尝试的先前电子邮件 ID/帐户相关联。 JSON 中存在的访问令牌和其他参数与新的电子邮件 ID/帐户无关。因此,为了使其运行,您只需删除“.credentails”文件夹并再次运行程序。现在,程序会打开浏览器并要求您授予权限。
在python中删除包含文件的文件夹
import shutil
shutil.rmtree("path of the folder to be deleted")
你可以在程序末尾添加这个
【讨论】:
【参考方案5】:最近我开始探索 Gmail API,我采用的方法与郭提到的相同。但是,当我们的用户数量或更多时,它会花费时间和太多的电话。在域范围委派之后,我的期望是管理员 ID 将能够访问委派的收件箱,但似乎我们需要为每个用户创建服务。
【讨论】:
这是一个答案吗?还是评论?请仅在答案部分发布答案。以上是关于Gmail API 返回 403 错误代码和“<user email> 的委托被拒绝”的主要内容,如果未能解决你的问题,请参考以下文章
在 c# 中使用 gmail API 修改消息标签时权限不足 [403] 错误
错误 403,元数据范围不允许格式 FULL 。 Web 应用程序 Gmail API 通过邮递员获取消息
调用 GMAIL API 时出现间歇性错误 - “调用者没有权限”
使用 api 密钥使用 Web API 时,出现以下错误 - 远程服务器返回错误:(403) Forbidden