Reputation: 125
I want to upload a pdf file to Google Drive using curl
, for automated testing purposes.
I have created an account on Google Cloud Platform(got client ID and Secret) and enabled the Google Drive API.
All the methods to connect using OAuth2 involve a web browser or clicking some buttons, which I'm not intending to do.
Is there any way to make the whole process of authenticating using OAuth2 and getting an access token to be able to upload a file using it, using ONLY curl
commands in the cmd terminal?
Thanks.
Upvotes: 12
Views: 13662
Reputation: 329
Google's bearer tokens (OAuth 2.0 access_token) are ephemeral which means after, say, an hour they expire and need to be refreshed. Further, from what I've seen, Google's refresh issues a new bearer token and expiration.
I wrote some scripts that use perl, jq and curl to obtain a new bearer token and refresh an expired or about to expire bearer token. They are working as of this posting in 2023. I don't know of any way that you could do that just using curl, you would also need some scripting language.
(Note as of 2023 the out-of-band method in the selected answer no longer works. I have added a comment to the gist that answer links to.)
Upvotes: 0
Reputation: 3177
i wanted to do the same thing for some PC app (language doesn't matter Java / Node / Command line Curl / or even client side JavaScript)
i couldn't found a simple explanation (beside @DaImTo here), but it works only for native apps,
https://accounts.google.com/o/oauth2/auth?client_id=[YOUR CLIENT-ID]&redirect_uri=[YOUR SITE URL]&scope=https://www.googleapis.com/auth/drive&response_type=code&include_granted_scopes=true&access_type=offline&state=state_parameter_passthrough_value
curl --request POST --data "code=[YOUR CODE]&client_id=[YOUR CLIENT ID]&client_secret=[YOUR CLIENT SECRET]&redirect_uri=[YOUR SITE URL]&access_type=offline&grant_type=authorization_code" https://oauth2.googleapis.com/token
response should look like this:
{
"access_token": "YYYY",
"expires_in": 3599,
"refresh_token": "ZZZZ",
"scope": "https://www.googleapis.com/auth/drive",
"token_type": "Bearer"
}
if you receive an error like this:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "parseError",
"message": "Parse Error"
}
],
"code": 400,
"message": "Parse Error"
}
}
it probably means the file type is incorrect, if you receive an error like this:
{
"error": "invalid_grant",
"error_description": "Bad Request"
}
it usually means that the user has revoked the app permission (or code obtained in step 9 has expired), so simply repeat step 9
curl -X POST -L -H "Authorization: Bearer YYYY" -F "metadata={name :'[FILE_NAME.EXT]'};type=application/json;charset=UTF-8" -F "file=@[FILE_NAME.EXT];type=application/javascript" "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart"
replace the [FILE_NAME.EXT] with your file name and file extension, and run the command from the folder where the file reside (or add the path to the file), for example:
curl -X POST -L -H "Authorization: Bearer YYYY" -F "metadata={name :'myScript.js'};type=application/json;charset=UTF-8" -F "[email protected];type=application/javascript" "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart"
this example uploads a javascript file, if you want to upload a different type - just replace the "application/javascript" with your file type, you can see accepted types here
curl --request POST --data "access_type=offline&refresh_token=[ZZZZ]&client_id=[YOUR CLIENT ID]&client_secret=[YOUR CLIENT SECRET]&grant_type=refresh_token" https://oauth2.googleapis.com/token
Upvotes: 1
Reputation: 117196
The following commands will show you how to authorize to Google using Curl. You are going to have to use the web browser at least once in order to get the refresh token once you have a refresh token you can just use the command to request a new one again after.
# Client id from Google Developer console
# Client Secret from Google Developer console
# Scope this is a space separated 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=[Authentication 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
Tips:
Upload is in two parts you need to upload your metadta, then a file stream of the actual file.
There is a difference between create and update. If its an existing file you will need to use update not create or your going to get a new file every time.
Code ripped from GoogleAuthenticationCurl.sh
if you want fully hands free, then you should look into a service account, I cant help you do that in curl im not even sure its possible due to all the security and generation of tokens.
THe official documentation for refresh tokens and their possible expiration
Upvotes: 11