Assuming there are three steps,
STEP 1:
I get through Step 1 if (and only if) I ignore the redirect_url
parameter listed necessary on various how-to links. So it's...
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'
At that point the return is...
{"device_code": "[device_code]", "user_code": "[user_code]", "expires_in": 1800, "interval": 5, "verification_url": "https://www.google.com/device"}
So far so good.
STEP 2: This is where I get stuck. Tried various iterations of the following:
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'
The above returns
{"error" : "invalid_grant", "error_description" : "Malformed auth code."}
If grant_type
is changed to 'http://oauth.net/grant_type/device/1.0'
, response is
{"error" : "invalid_request", "error_description" : "Parameter not allowed for this message type: redirect_uri"}
If redirect_uri
is removed the response is
{"error" : "authorization_pending"}
The above cURL attempts were cobbled together referencing the following links... 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/
Stymied!
Per request, the goal here: develop a method of being alerted when files upload, and have a system in place that can selectively and systematically download based on a variety of queries.
The reason we're not doing this with Google Drive's web UI: The file sizes are pretty big: 10-50gb per file, and Google can't batch download without zipping first, and can't zip anything over a size that's smaller than our smallest file.
The reason we're not doing this with Google Drive's APP: It's not possible (AFAIK) to manage which files do and don't download locally, and there's no ability (again AFAIK) to store to an external volume.
Also, we're integrating a workflow database into our media uploads and downloads: tracking, dates, progress notes, versions, etc., none of which is part of any existing Google system. So the goal here is to see what's options Google's API might hold for all this.
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
Put this into a browser window. And copy the code there into step two. I suspect the issue is with the code you are getting returned from the first step
There was a link to the gist for the code used in my blog post you linked.
As you can see the post data should be sent as one long query string separated with &
--data 'client_id=[Application Client Id]&client_secret=[Application Client Secret]&refresh_token=[Refresh token granted by second step]&grant_type=refresh_token' \
Code ripped from 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
This appears to work fine. I removed the header which isnt needed and all the (')'s you had in your code I didnt have any issues getting a refresh token returned
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
response:
{
"access_token" : "pO4LBSreV_r2i8kPklXVTqylXbMXip4OmQ0ZgRW0qZ8_b1ZP_zPJv0Xc_Qqsj9nM5ryWb7C81dYNFkO_bC6ifWA68dIlz40a0owG4GWpbZ2ufkHNXgre4",
"expires_in" : 3600,
"refresh_token" : "1/mEADfx6ffWULNBNFrKnlqOlK1uGL8Z546qBCHg",
"token_type" : "Bearer"
}
ANSWER:
A partial answer to the question -- 'partial' because it doesn't use pure cURL-- but it was possible to get it working using PHP to prep some of the dynamic and SSL values and then run cURL from within PHP.
The key reference for the following comes from Google's documentation here: 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": "[email protected]",
"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/[email protected]"
}');
}
function Process_cURL($ThisUrl,$ThisType,$ThisHeader,$ThisData){
//Handler for a variety of cURL calls. Returns JSON string
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With