谷歌驱动服务帐户和

谷歌驱动服务帐户和

本文介绍了谷歌驱动服务帐户和“请求中的未经授权的客户端或范围"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有 3 个使用驱动 sdk 的服务帐户.

I have 3 service accounts that are using the drive sdk.

1 有效,2 无效.

返回的错误是Error refresh the OAuth2 token, message: '{ "error" : "unauthorized_client", "error_description" : "Unauthorized client or scope in request." }'"

The error that comes back is "Error refreshing the OAuth2 token, message: '{ "error" : "unauthorized_client", "error_description" : "Unauthorized client or scope in request." }'"

所有 3 个帐户均已在开发者控制台中注册.所有这 3 个都被授权在 Google Apps 控制台中进行托管客户端 API 访问".所有 3 都具有范围https://www.googleapis.com/auth/drive.readonly".驱动器中的所有 3 个,都有一个特定的文件夹供仅查看"共享.

All 3 accounts are registered in the developer console. All 3 are authorised for "Managed Client API access" within Google Apps Console. All 3 have the scope "https://www.googleapis.com/auth/drive.readonly". All 3 in drive, has a specific folder for it shared for "view only".

我正在使用 PHP,我向页面传递了一个参数,该参数称为类型",它反映了帐户的用途,1 用于公共,1 用于会员,1 用于管理员.

I am using PHP and I pass one parameter to the page which is called "type" and reflects what the purpose of the account is for, 1 for public, 1 for member and 1 for admin.

例如

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

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

The p12 certificate and user values are stored on the server. All "ini" files have the same structure of values, client_id, client_email, scope and query filter. In all cases the only item that changes between the files is the client_id and 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) . "
";
?>

每个ini文件的结构如下

Each ini file is structured as follows

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'"

我无法弄清楚为什么当我对所有服务帐户都进行了相同的过程时,这对一个服务帐户而不是其他服务帐户有效.任何想法和帮助表示赞赏.

What I just cannot work out is why this works for one service account and not the others when I have gone through the same process for all of them. Any ideas and help appreciated.

推荐答案

感谢您的这篇文章以及您对Resolved by remove the line $credentials -> sub = $service_account_email;"

Thanks for this post and your comment about "Resolved by removing the line $credentials -> sub = $service_account_email;"

我面临着类似的问题 这里.显然, $credentials ->sub = $service_account_email 仅适用于在 Google Developers Console 中创建的第一个/主要服务帐户.除此之外,它还会在某些 OAuth2 范围内产生意外错误(就像我在 Fusion Tables 中遇到的那样).

I am facing a similar issue here. Apparently, $credentials -> sub = $service_account_email is only accepted for the first/primary service account created in the Google Developers Console. Besides that, it will also produce unexpected errors with certain OAuth2 scopes (as what I encountered with Fusion Tables).

因此,这里是一般建议:

Hence, here is the general advise:

不要包含 $credentials ->sub = $service_account_email 不必要.

仅当您尝试冒充差异用户(条件是适当的设置具有已在 Google Apps 管理控制台中正确完成).

尽管在某些情况下它可能不会产生任何错误,但在将服务帐户本身的电子邮件地址包含在 JWT 声明集中作为sub"字段的值时,会出现一些意外行为.

这篇关于谷歌驱动服务帐户和“请求中的未经授权的客户端或范围"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 05:14