I am a newbie in Google API. I start my project with Google Drive API and I follow the tutorial in this google cloud document.
On the Google Cloud Console - I create my project, enable the "Google Drive API". After that, I create a "Service account" and its private key, and then save the "JSON private key file" to my local server. At this process, I didn't create any "oAuth 2.0 Client IDs" or "API Keys".
This is my "JSON private key file" in my local server:
{
"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]*"
}
and this is my PHP file for request an "Access Token" from 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;
Above code contain 2 function for url-safe base64 like this:
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));
}
I open the php file on my browser and see the result like this:
I click on the link in the picture and it bring me to a user consent page.
Does it mean my HTTP request for access token failed or else? What're the mistakes I did?
I see that you are trying to do this manually and i would like to recomend that you not. Creating the jws to authorize a service account is tricky. Its much easer to just use the Google php client library
My sample 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();
}
}
Really let the client library do all the heavy lifting. The Google analytics api has a nice service account example for php. Just take the authorization stuff and replace google analytics with drive. Let me know if you have any issues Google analytics quickstart