I want to reuse the OAuth2 client-secret of a Google Apps script project to access Google APIs on behalf of this script (e.g. via Sheets API reading a spreadsheet where the script has access). Users with a Google account granted the necessary scopes to the script. Now I'd like to replace the script with a new app without asking the users again for user consent. Typically, when the script (or the app) runs the users would be offline.
My first question would be, if this scenario is a supported OAuth2 use-case with Google API authorization, and if so, what would be the best way to implement it, especially to prevent security issues?
Client secrets of the script
- OAuth2 client-secret file of the script from Google API Console, under Credentials. Also see Credentials, access, security, and identity and Setting up OAuth 2.0
The client-secrets.json looks like this:
{"web":{
"client_id": "57...1t.apps.googleusercontent.com",
"project_id": "project-id-95...70",
"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_secret": "K2...y1",
"redirect_uris": ["https://script.google.com/oauthcallback"]
}}
The file would be deployed with the app code (App Engine). But an alternate location such as Cloud Storage would be possible.
OAuth2 access token
In absence of the user, I would like to use the client ID and secret with the same scopes that were granted to the script originally, for getting an access token from the Google authorization server, something like this:
HTTP 200 OK
Content-type: application/json
{
"access_token": "987tghjkiu6trfghjuytrghj",
"scope": "foo bar",
"token_type": "Bearer"
}
I would like to use the access token in the HTTP Bearer header for the requests to the Sheets API on behalf of the old script.
Client_credentials request to authorization server
My (limited) understanding is, that I can use the grant-type client_credentials
to get the access token from the authorization server. The request would look like this:
POST /o/oauth2/token
Host: https://accounts.google.com
Content-Type: application/x-www-form-urlencoded
Accept: application/json
Authorization: Basic Base_64_string
grant_type=client_credentials&
scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fspreadsheets
Where the Basic HTTP authorization is client_id:client_secret
values, separated by a colon, and base64 encoded.
If I ditch grant_type
or scope
in the body, I will get corresponding errors.
The version as above resulted in: {\n "error" : "invalid_request"\n}
response, no specifics provided. I have tried with client_id
and client_secret
in the body in combination with and without the Authorization header, all with the same error.