php - 使用 Google App Engine 应用程序更新 Google 群组订阅

标签 php google-app-engine google-workspace service-accounts

我正在 Google App Engine (PHP) 上构建一个小应用程序,旨在将外部源与 google 组同步以获得最新的邮件列表。 (它应该作为 GAE cron 任务运行)

Google App Engine 项目和 google 组位于 GSuite 域内。

The sources are here , 见 firestore2ggroup.php

我遇到的问题与安全相关,当我尝试调用 API 时,我收到 403 错误,没有其他详细信息。

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "forbidden",
    "message": "Not Authorized to access this resource/api"
   }
  ],
  "code": 403,
  "message": "Not Authorized to access this resource/api"
 }
}

我已按照此处描述的步骤作为起点,因为它接近我的需要:

https://medium.com/@Skaaptjop/access-gsuite-apis-on-your-domain-using-a-service-account-e2a8dbda287c

所以我做了以下事情:

  • 在 Google Cloud Console 中:

    • 部署 Google App Engine 项目
    • 转到 IAM、服务帐户、复制 GAE 服务帐户的唯一 key 并启用“域范围委派”
    • 创建一个 JSON 私钥
    • 使用“Service Directory Admin”(以及 firestore 的 Cloud Data Store 用户)更新服务帐户
  • 在 GSuite 管理员中:

更新:我什至尝试添加更多权限,但它仍然不起作用:

enter image description here

在我的项目中,我复制了 JSON 私钥并在 app.yaml 中设置了变量 GOOGLE_APPLICATION_CREDENTIALS 和文件名。

我使用这个 Google 库访问 Google 组:

Composer 需要 google/apiclient:^2.0

try
{
  $client = new Google_Client();
  $client->setApplicationName('Pegass2GGroup');
  $client->setScopes(
    [
      Google_Service_Directory::ADMIN_DIRECTORY_GROUP,
      Google_Service_Directory::ADMIN_DIRECTORY_GROUP_MEMBER,
      Google_Service_Directory::ADMIN_DIRECTORY_USER
    ]);
  $client->useApplicationDefaultCredentials(true);
  $access_token = $client->fetchAccessTokenWithAssertion();

  print_r($access_token);

  $service = new Google_Service_Directory($client);

  /** @var $members  Google_Service_Directory_Members */
  $members = $service->members->listMembers($MAILING_LIST);

  /** @var $member  Google_Service_Directory_Member */
  foreach ($members as $member)
  {
    print_r($member->getEmail());
  }
  echo "</pre>";
}
catch(Exception $e)
{
  print_r($e);
  echo "</pre>";
}

我可以看出私钥已加载,因为 print_r($e) 给出了一个很长的异常并且列出了 key 。

print_r($access_token);给出以下内容:

Array
(
    [access_token] => dag2qssffdVpRZEr...0BsM_QUgQ
    [expires_in] => 3599
    [token_type] => Bearer
    [created] => 1586787451
)

$MAILING_LIST : 是邮件列表的完整电子邮件地址

最佳答案

所以上面的代码缺少模拟。

$client->setSubject($EMAIL_TO_IMPERSONATE);//admin@mydomain.com

在访问域中其他成员的数据时充当此电子邮件。

然后我得到了这个错误:

(
    [errors:protected] => 
    [message:protected] => {
  "error": "unauthorized_client",
  "error_description": "Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested."
}

这是因为我要求:

  Google_Service_Directory::ADMIN_DIRECTORY_GROUP,
  Google_Service_Directory::ADMIN_DIRECTORY_GROUP_MEMBER,
  Google_Service_Directory::ADMIN_DIRECTORY_USER

但我忘记在 GSuite API 安全管理中添加以下内容:

  Google_Service_Directory::ADMIN_DIRECTORY_USER

添加后,成功了。 所以如果你请求一组角色,所有的都必须被授予。 即使我没有使用 Google_Service_Directory::ADMIN_DIRECTORY_USER,我在连接时询问它并且其中一个未被授予这一事实也会阻止整个连接。

我想我只需要 Google_Service_Directory::ADMIN_DIRECTORY_GROUP_MEMBER

到目前为止,我仅列出组成员的工作范围是:

184920....0484899(客户端 ID)

https://www.googleapis.com/auth/admin.directory.group,https://www.googleapis.com/auth/admin.directory.group.member,https://www.googleapis.com/auth/apps.groups.settings,https://www.googleapis.com/auth/groups,https://www.googleapis.com/auth/admin.directory.user

关于php - 使用 Google App Engine 应用程序更新 Google 群组订阅,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61191249/

相关文章:

google-app-engine - 从 google go 中重命名的类型进行转换

php - 使用 DB::query 处理 Silverstripe 中的 MySQL 错误

php - 如果未完成注销,如何存储用户登录持续时间?

google-app-engine - Google 云端硬盘按服务帐户更改权限

google-apps-script - OAuth 同意屏幕 - 能够删除应用程序 Logo : old solution is no longer working

google-workspace - G Suite Shared Drive(Team Drive) 角色管理

google-api - Google API 给出未经授权的 token 错误

php - json_encode 是否足够的 XSS 保护?

php - 在子文件夹中创建 txt 文件列表文件

google-app-engine - webapp2 重定向解释