Google驱动器服务帐户和“未经授权的客户端或请求中的作用域” [英] Google drive service account and "Unauthorized client or scope in request"

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

问题描述

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



1,作品,2不要。



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



所有3个帐户都在开发者控制台中注册。
所有3个都被授权在Google Apps Console中使用托管客户端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__。 /安全/;
$ certificate = $ path。 $类型。 的.p12\" ;
$ ini_path = $ path。 $类型。 .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
);
$凭证 - > sub = $ service_account_email;

$ google_client = new Google_Client();

$ google_client - > setAssertionCredentials($凭证);
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 - >档案 - > listFiles($参数);

$ result = array_merge($ result,$ files - > getItems());
$ pageToken = $文件 - > getNextPageToken();
} catch(Exception $ e){
print发生错误:。 $ e - >的getMessage();
$ pageToken = NULL;
}
} while($ pageToken);

echo json_encode($ result)。 \\\
;
?>

每个ini文件的结构如下

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

我为什么不能解决这个问题,这就是为什么这对一个服务帐户起作用,而当我为所有服务帐户完成相同的过程时,这种服务帐户不起作用。任何想法和帮助表示赞赏。 解决方案

感谢这篇文章和您对解决的评论 c $ c> $ credentials - > sub = $ service_account_email;



我正面临类似的问题此处。显然, $ credentials - > sub = $ service_account_email 仅适用于在Google Developers Console中创建的第一个/主要服务帐户。除此之外,它还会在某些OAuth2范围内产生意想不到的错误(正如我在Fusion Tables中遇到的情况)。

因此,以下是一般建议:


请勿包含 $ credentials - > sub = $ service_account_email 不必要的。

只有在您尝试模拟
差异用户时(以相应设置具有
的情况正确)在Google Apps管理控制台中完成)。


尽管在某些情况下它可能不会产生任何错误,但在将JWT声明集中的服务帐户本身的电子邮件地址作为子领域。



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

1, works, 2 do not.

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

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

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.

For example

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

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.

My code is as follows:

    <?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";
?>

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.

解决方案

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

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:

DO NOT include $credentials -> sub = $service_account_email unnecessarily.

Only do this when you are trying to impersonating a difference user (with the condition that the appropriate setup has been correctly done in Google Apps Admin Console).

Even though it may not produce any error under certain cases, there are some unexpected behaviors when including an email address of the service account itself in the JWT claim set as the value of the "sub" field.

这篇关于Google驱动器服务帐户和“未经授权的客户端或请求中的作用域”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆