Google 驱动器 API - 服务帐户:请求访问令牌

Google Drive API - Service Account : make a request for access token

我是 Google API 的新手。我从 Google Drive API 开始我的项目,然后按照 this google cloud document.

中的教程进行操作

在 Google Cloud Console - 我创建我的项目,启用“Google Drive API”。之后,我创建一个“服务帐户”及其私钥,然后将“JSON 私钥文件”保存到我的本地服务器。在此过程中,我没有创建任何“oAuth 2.0 客户端 ID”或“API 密钥”。

这是我本地服务器中的“JSON 私钥文件”:

{
  "type": "service_account",
  "project_id": "coastal-scanner-338317",
  "private_key_id": "a093062296b1cbdecab6133f6b91e470bfbca0e4",
  "private_key": "-----BEGIN PRIVATE KEY-----\n*[My Private Key]*\n-----END PRIVATE KEY-----\n",
  "client_email": *[My Client Email]*,
  "client_id": *[My Client ID]*,
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/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/*[My Client Email]*"
}

这是我的 PHP 文件,用于从 google.

请求 “访问令牌”
    //Create Service Account's JWT
    $serviceFile = './mykey.json';  //My Private key file
    $scope='https://www.googleapis.com/auth/drive';  
    
    // Get Data from Google Service Account Oauth2 json file
    $service = json_decode(file_get_contents($serviceFile));
    
    $header = '{"alg":"RS256","typ":"JWT"}';
$aud = $service->auth_uri; // 'https://oauth2.googleapis.com/token'
    $iat = time(); $exp =  $iat + 3600;
    $claimset = '{"iss":"' . $service->client_email . '","scope":"' . $scope . '","aud":"' . $aud . '","exp":' . $exp . ',"iat":' . $iat . '}';

//URL-safe Base64 header and claimset
    $hc = base64url_encode(mb_convert_encoding($header,'UTF-8')) . '.' . base64url_encode(mb_convert_encoding($claimset,'UTF-8'));
    
// Signature with Sha256withRSA follow Google spec = RS256
    $bytepkey = openssl_pkey_get_private($service->private_key);

    openssl_sign($hc,$signature,$bytepkey,'sha256');
    openssl_free_key($bytepkey);

    $assertion =  $hc . '.' . base64url_encode($signature);
    $grant_type = urlencode('urn:ietf:params:oauth:grant-type:jwt-bearer');
    $param = "grant_type={$grant_type}&assertion={$assertion}";

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $service->auth_uri);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $user_agent);
    curl_setopt($ch, CURLOPT_POST , 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS , $param);
    $result = curl_exec($ch);
    echo $result;

以上代码包含 url-safe base64 的 2 个函数,如下所示:

function base64url_encode($data) {
  return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
function base64url_decode($data) {
  return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
}

我在浏览器中打开 php 文件,看到的结果如下:

我点击图片中的 link,然后我进入了用户同意页面。

这是否意味着我对访问令牌的 HTTP 请求失败了?我犯了什么错误?

我看到您正在尝试手动执行此操作,但我建议您不要这样做。创建 jws 来授权服务帐户很棘手。仅使用 Google php 客户端库

就容易多了

我的样本ServiceAccount.php

require_once __DIR__ . '/vendor/autoload.php';

// Use the developers console and download your service account
// credentials in JSON format. Place the file in this directory or
// change the key file location if necessary.
putenv('GOOGLE_APPLICATION_CREDENTIALS='.__DIR__.'/service-account.json');

/**
 * Gets the Google client refreshing auth if needed.
 * Documentation: https://developers.google.com/identity/protocols/OAuth2ServiceAccount
 * Initializes a client object.
 * @return A google client object.
 */
function getGoogleClient() {
    return getServiceAccountClient();
}


function getServiceAccountClient() {
    try {   
        // Create and configure a new client object.        
        $client = new Google_Client();
        $client->useApplicationDefaultCredentials();
        $client->addScope([YOUR SCOPES HERE]);
        return $client;
    } catch (Exception $e) {
        print "An error occurred: " . $e->getMessage();
    }
}

真正让客户端库完成所有繁重的工作。 Google 分析 api 有一个很好的服务帐户示例 php。只需获取授权内容并将 google analytics 替换为 drive。如果您有任何问题,请告诉我 Google analytics quickstart

我回来更新我的错误

我上面写的所有代码都可以工作,但唯一的问题是“我没有 Google API 帐户”。

使用我朋友的帐户后。它完成了工作。

这是我的蠢事,打扰了好心人。再次抱歉,非常感谢您的帮助。