当前位置: 首页 > 知识库问答 >
问题:

谷歌驱动器服务帐户和“未经授权的客户端或范围在请求”

童铭晨
2023-03-14

1,有效,2不可行。

返回的错误是“刷新OAuth2令牌时出错,消息:”{“error”:“unauthorized_client”,“error_description”:“请求中未授权的客户端或作用域。”}“

所有3个帐户都在开发人员控制台中注册。所有3个都被授权在谷歌应用程序控制台内进行“托管客户端API访问”。所有3个都有作用域“https://www.googleapis.com/auth/drive.readonly”。所有3在驱动器中,有一个特定的文件夹为它共享“仅查看”。

我使用PHP和我传递一个参数到页面称为“类型”,反映什么帐户的目的,1为公共,1为成员,1为管理。

例如

http://www.somehost.com/oauth_client.php?type=googledrive_admin

p12证书和用户值存储在服务器上。所有“ini”文件都具有相同的值结构、client_id、client_email、作用域和查询过滤器。在所有情况下,文件之间唯一更改的项是client_id和client_email。

    <?php

 include (__DIR__ . "/google-api-php-client/autoload.php");

 google_api_php_client_autoload("Google_Auth_AssertionCredentials");
 google_api_php_client_autoload("Google_Client");
 google_api_php_client_autoload("Google_Service_Drive");
 google_api_php_client_autoload("Google_Service_OAuth2");

 $type = $_GET['type'];
 $path = __DIR__ . "/secure/";
 $certificate = $path . $type . ".p12";
 $ini_path = $path . $type . ".ini";

 $ini = parse_ini_file($ini_path);
 $service_scope = $ini['scope'];
 $service_account_id = $ini['id'];
 $service_account_email = $ini['email'];
 $service_query = $ini['q'];

 $service_account_key = file_get_contents($certificate);
 $credentials = new Google_Auth_AssertionCredentials(
  $service_account_email,
  array($service_scope),
  $service_account_key
 );
 $credentials -> sub = $service_account_email;

 $google_client = new Google_Client();

 $google_client -> setAssertionCredentials($credentials);
 if ($google_client -> getAuth() -> isAccessTokenExpired()) {
  $google_client -> getAuth() -> refreshTokenWithAssertion(); **//FAILS HERE**
 }  

 $drive = new Google_Service_Drive($google_client);

 $result = array();
 $pageToken = NULL;

 do {
  try {
   $parameters = array();
   if ($pageToken) {
    $parameters['pageToken'] = $pageToken;
   }
   $parameters['q'] = $service_query;

   $files = $drive -> files -> listFiles($parameters);

   $result = array_merge($result, $files -> getItems());
   $pageToken = $files -> getNextPageToken();
  } catch (Exception $e) {
   print "An error occurred: " . $e -> getMessage();
   $pageToken = NULL;
  }
 } while ($pageToken);

 echo json_encode($result) . "\n";
?>

每个ini文件的结构如下

id="35{code}.apps.googleusercontent.com"
email="35{code}@developer.gserviceaccount.com"
scope="https://www.googleapis.com/auth/drive.readonly"
q="mimeType != 'application/vnd.google-apps.folder'"

我只是弄不明白为什么当我对所有服务帐户都经历了相同的过程时,这对一个服务帐户有效,而对其他服务帐户无效。任何想法和帮助都很感激。

共有1个答案

徐绪
2023-03-14

感谢这篇文章和您关于“通过删除$credentials->sub=$service_account_email;行来解决”的评论

我在这里也面临着类似的问题。显然,$credentials->sub=$service_account_email只接受在Google Developers控制台中创建的第一个/主要服务帐户。除此之外,它还会在某些OAuth2作用域中产生意外错误(就像我在Fusion表中遇到的那样)。

因此,以下是一般性建议:

 类似资料:
  • 我为我的帐户name@steelkiwi.com(谷歌应用程序)创建了服务帐户,我的应用程序运行良好。然后我为我的个人帐户name@gmail.com创建了服务帐户,为我的应用程序使用这个新的凭据,现在当我试图插入文件时,我得到错误500和下一个文本: HttpError 500请求https://www.googleapis.com/upload/drive/v2/files时?quotause

  • 我想使用谷歌驱动器作为一个网站的准CMS工作,我正在使内容所有者可以编辑他们的内容使用谷歌驱动器。我希望使用一个可以访问Google Drive的特定用户帐户(在写这篇文章时,服务帐户不能直接访问Google Drive),并且能够与内容所有者共享文档。 在阅读了API和教程之后,我在委托中找到了答案:https://developers.google.com/drive/development

  • 我们需要访问谷歌日历API与服务器应用程序,以创建事件和邀请与会者。谷歌建议使用服务帐户的应用程序。 这里的主要问题是与会者邀请参加活动,因为如果没有域范围的授权,服务帐户就不能这样做(请参见img)。 组织不希望授予服务帐户访问所有用户数据的权限。所以,我想知道我们是否可以将域范围的授权委托给域的一个用户?(限制访问以使用其他用户的数据)。 附言。它只是关于谷歌日历API。 非常感谢你的帮助。

  • 我正在编写一个类,用于创建对BigQuery和Google云存储的授权。 在过去,我曾使用,但已被弃用。我试图使用,但我发现它只允许我使用,而我需要。 我知道可以从转换为,但我不知道如何将它们转换成相反的方向(转换为)。例如,我像这样创建连接: 有人能给我指明如何实现这一目标的方向吗? 谢谢!

  • 我是第一次使用谷歌API,我在尝试下载文件对象“下载Url”属性的文件时遇到问题。我当前正在使用“服务帐户”选项以及关联的服务帐户电子邮件和 P12 证书。 但是,URL返回“https://doc-08-68-docs.googleusercontent.com/docs/securesc/bteg36c1tifegg79l2ov17og25612tet/gk7kn52ahe4d0to7d6ht

  • 之后,我得到以下错误: 我们使用的是restapi.php (a)我们使用的是G套件“基本版”;那有什么限制吗?(b)我们从PHP(7.0)环境中调用G-Suite API;是否有任何已知的问题,因为环境仍然标记为'(Beta)'。(c)是否有任何样例/教程可以给出解决我们问题的指针。