【问题标题】:How to connect to the Google Drive API using cURL?如何使用 cURL 连接到 Google Drive API?
【发布时间】:2018-07-17 05:00:24
【问题描述】:

假设有三个步骤,

  1. 获取设备代码,
  2. 获取身份验证令牌,
  3. 连接到 Google 云端硬盘。

第 1 步: 如果(且仅当)我忽略了在各种操作方法链接上列出的必要的 redirect_url 参数,我将通过第 1 步。所以...

curl -d 'client_id=*client_id*' -d 'scope=https://www.googleapis.com/auth/drive.file' -d 'response_type=code' 'https://accounts.google.com/o/oauth2/device/code'

那时回报是... {"device_code": "[device_code]", "user_code": "[user_code]", "expires_in": 1800, "interval": 5, "verification_url": "https://www.google.com/device"}

到目前为止一切顺利。

第 2 步: 这就是我卡住的地方。尝试了以下各种迭代:

curl -H 'Content-Type: application/x-www-form-urlencoded' -d 'client_id=**client_id**' -d 'client_secret=*client_secret*' -d 'grant_type=authorization_code' -d 'redirect_uri=urn:ietf:wg:oauth:2.0:oob' -d 'code=[device_code_from_above]' 'https://accounts.google.com/o/oauth2/token'

以上返回

{"error" : "invalid_grant", "error_description" : "Malformed auth code."}

如果grant_type 更改为'http://oauth.net/grant_type/device/1.0',则响应为

{"error" : "invalid_request", "error_description" : "Parameter not allowed for this message type: redirect_uri"}

如果redirect_uri 被删除,则响应为

{"error" : "authorization_pending"}

上面的 cURL 尝试是参考以下链接拼凑在一起的... https://developers.google.com/identity/protocols/OAuth2ForDevices

http://www.visualab.org/index.php/using-google-rest-api-for-analytics#comment-157284

list google drive files with curl

Google Drive not listing files in folder

Not able to fetch Google OAuth 2.0 access token

https://www.daimto.com/google-authentication-with-curl/

受阻!

编辑

根据请求,这里的目标是:开发一种在文件上传时收到警报的方法,并建立一个可以根据各种查询有选择地、系统地下载的系统。

我们不使用 Google Drive 的 Web UI 执行此操作的原因:文件大小非常大:每个文件 10-50gb,而且 Google 无法在不先压缩的情况下批量下载,并且无法压缩超过大小的任何内容这比我们最小的文件还小。

我们不使用 Google Drive 的 APP 执行此操作的原因:无法 (AFAIK) 管理哪些文件可以在本地下载和不可以在本地下载,并且无法(再次 AFAIK)存储到外部卷。

此外,我们正在将工作流数据库集成到我们的媒体上传和下载中:跟踪、日期、进度说明、版本等,这些都不属于任何现有的 Google 系统。所以这里的目标是看看 Google 的 API 可以为这一切提供哪些选项。

【问题讨论】:

  • 您究竟要粘贴到“device_code_from_above”中的内容。出于安全考虑,请随意混淆实际代码值。它应该类似于“4/AADhY_JAsynoD1SEAMbmt-oVmO_kWbFJ_XV3qap7XVd7iAmpjrgkOa5kAefLEpl38pcKEBXIOxQ568q_kzU”
  • 第 1 步将“device_code”作为 98 个字符的字符串返回,该字符串之前以“4/AA”开头,最近以“AH-1N”开头。
  • "AH..." 不是验证码,因此出现错误。您确定要取消测试运行之间的授权,并且您是否将设备代码与 Auth 代码混淆了。
  • 可能值得更新您的问题以解释您的方案以及您希望实现的目标。没有浏览器就无法授权 API/应用程序,因为在用户授权之前,他必须首先通过 Google 网络登录和会话 cookie 进行身份验证。

标签: curl oauth google-drive-api google-oauth


【解决方案1】:

第一步获取代码

https://accounts.google.com/o/oauth2/auth?client_id=[Application Client Id]&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=[Scopes]&response_type=code

把它放到浏览器窗口中。并将那里的代码复制到第二步。我怀疑问题出在您从第一步返回的代码上

第二步兑换码

有一个链接指向您链接的我的博客文章中使用的代码的要点。

如您所见,帖子数据应作为一个用 & 分隔的长查询字符串发送

--data 'client_id=[Application Client Id]&client_secret=[Application Client Secret]&refresh_token=[第二步授予的刷新令牌]&grant_type=refresh_token' \

googleauthenticationcurl.sh 窃取的代码

# Client id from Google Developer console
# Client Secret from Google Developer console
# Scope this is a space seprated list of the scopes of access you are requesting.

# Authorization link.  Place this in a browser and copy the code that is returned after you accept the scopes.
https://accounts.google.com/o/oauth2/auth?client_id=[Application Client Id]&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=[Scopes]&response_type=code

# Exchange Authorization code for an access token and a refresh token.

curl \
--request POST \
--data "code=[Authentcation code from authorization link]&client_id=[Application Client Id]&client_secret=[Application Client Secret]&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code" \
https://accounts.google.com/o/oauth2/token

# Exchange a refresh token for a new access token.
curl \
--request POST \
--data 'client_id=[Application Client Id]&client_secret=[Application Client Secret]&refresh_token=[Refresh token granted by second step]&grant_type=refresh_token' \
https://accounts.google.com/o/oauth2/token

-d 不带 (') 的

这似乎工作正常。我删除了不需要的标头和代码中的所有 (') 我在返回刷新令牌时没有任何问题

curl -d client_id=103456123799103-vpdthl4ms0soutcrpe036ckqn7rfpn.apps.googleusercontent.com -d client_secret=uxpj6hx1H2N5BFqdnaNhIbie -d grant_type=authorization_code -d redirect_uri=urn:ietf:wg:oauth:2.0:oob -d code=4/AABvK4EPc__nckJBK9UGFIhhls_69SBAyidj8J_o3Zz5-VJN6nz54ew https://accounts.google.com/o/oauth2/token

回复:

{
  "access_token" : "pO4LBSreV_r2i8kPklXVTqylXbMXip4OmQ0ZgRW0qZ8_b1ZP_zPJv0Xc_Qqsj9nM5ryWb7C81dYNFkO_bC6ifWA68dIlz40a0owG4GWpbZ2ufkHNXgre4",
  "expires_in" : 3600,
  "refresh_token" : "1/mEADfx6ffWULNBNFrKnlqOlK1uGL8Z546qBCHg",
  "token_type" : "Bearer"
}

【讨论】:

  • OP 使用 POST。当 curl 命令行中包含 -d 时,curl 会自动从 GET 切换到 POST。见linux.die.net/man/1/curl
  • 多个 -d args 与带有串联字符串的单个 -d arg 具有相同的效果。见 linux.die.net/man/1/curl
  • 我运行的测试使用单个 -d 参数,键/值对由 &s 分隔,以及单独的 -d 参数(应该没有区别), -d 参数的带引号和不带引号的值(通常没有区别,除非有空格)、原始值、转义值和 uri 编码值。我得到的错误明确指向“invalid_grant”(它永远不会改变、引用、转义等)这一事实表明这些论点在所有情况下都通过了,而且这不是 curl 语法本身,而是其他东西。跨度>
  • 也许这是一个线索:我尝试使用developers.google.com/drive/api/v3/about-auth 中列出的 9 个作用域中的每一个来运行第 1 步。只有一个 drive.file 返回了授权。其余的都返回{"error": "invalid_scope"}。我不知道 Google API 管理中的任何控件会在这里有所作为——也许是“角色”? (console.developers.google.com/iam-admin/roles),但考虑到正在使用的 client_id 是您认为可以访问所有 Google API 范围的“所有者”。
  • 尝试使用浏览器窗口而不是 curl 脚本获取代码。其他范围需要用空格分隔。 drive.file 是主要的文件,它使您可以访问所有内容
【解决方案2】:

回答:

这个问题的部分答案——“部分”,因为它不使用纯 cURL——但可以使用 PHP 来准备一些动态和 SSL 值,然后从 PHP 中运行 cURL .

以下内容的关键参考来自此处的 Google 文档: https://developers.google.com/identity/protocols/OAuth2ServiceAccount

echo GoogleTokenRequest();

function GoogleTokenRequest(){
    $GoogleApiKeyInfo=GoogleApiKeyInfo();
    $Header=array();
    $Header["alg"]="RS256";
    $Header["typ"]="JWT";
    $ClaimSet=array();
    $ClaimSet["iss"]=$GoogleApiKeyInfo["client_email"];
    $ClaimSet["scope"]="https://www.googleapis.com/auth/drive";
    $ClaimSet["aud"]="https://www.googleapis.com/oauth2/v4/token";
    $ClaimSet["iat"]=time();
    $ClaimSet["exp"]=$ClaimSet["iat"]+(60);
    $Jws=base64_encode(json_encode($Header)).".".base64_encode(json_encode($ClaimSet));
    $OpenSslRslts=openssl_sign($Jws,$Signature,$GoogleApiKeyInfo["private_key"],OPENSSL_ALGO_SHA256);//Ref: http://php.net/manual/en/function.openssl-sign.php
    $Jwt=$Jws.".".base64_encode($Signature);
    $SendVars=array();
    $SendVars["grant_type"]=("urn:ietf:params:oauth:grant-type:jwt-bearer");
    $SendVars["assertion"]=$Jwt;
    $SendVars=http_build_query($SendVars);
    $UrlDomain="www.googleapis.com";
    $UrlPath="/oauth2/v4/token";
    $UrlFull=$UrlDomain.$UrlPath;
    $CurlType="Post";
    $ThisHeader=[
        strtoupper($CurlType)." ".$UrlPath,
        "Host: ".$UrlDomain,
        "Content-Type: application/x-www-form-urlencoded"
    ];
    return Process_cURL("https://".$UrlFull,$CurlType,$ThisHeader,$SendVars);
}

function GoogleApiKeyInfo(){
    //The following JSON data is downloaded from https://console.developers.google.com/apis/credentials when creating a project API key.
    return json_decode('{
    "type": "service_account",
    "project_id": "XXX",
    "private_key_id": "XXXX",
    "private_key": "-----BEGIN PRIVATE KEY-----VeryLongMultiLineString-----END PRIVATE KEY-----\n",
    "client_email": "xxxx@xxxx.iam.gserviceaccount.com",
    "client_id": "XXXXX",
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://accounts.google.com/o/oauth2/token",
    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
    "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/xxxx@xxxx.iam.gserviceaccount.com"
    }');
}

function Process_cURL($ThisUrl,$ThisType,$ThisHeader,$ThisData){
    //Handler for a variety of cURL calls. Returns JSON string
}

【讨论】:

  • 你是我的救星!我花了 20 多个小时才找到这个不错的、纯粹的、没有库的解决方案。
猜你喜欢
  • 2022-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-18
  • 2016-02-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多