googleworkspace / apps-script-oauth2

An OAuth2 library for Google Apps Script.
https://developers.google.com/apps-script/
Apache License 2.0
1.56k stars 429 forks source link

How to pass data for access token as contentType: application/x-www-form-urlencoded #388

Open dking12 opened 2 years ago

dking12 commented 2 years ago

I couldn't find any examples that show how to utilize the library for services that require the access token request to provide data in the contentType of application/x-www-form-urlencoded. One example is using the Box API using the client credentials grant authorization method explained here: https://developer.box.com/guides/authentication/client-credentials/.

I've created a function which can perform this action but I'd prefer to use any built-in functions of this library.

erickoledadevrel commented 2 years ago

I believe the library uses application/x-www-form-urlencoded by default for all token requests. The library can handle the token being returns as either JSON or form encoded, but the requests are always form encoded.

mc-ct commented 2 years ago

@dking12 Have you figured out how to use this library with the Box API?

I have created a Box app with Authentication Method OAuth 2.0 with Client Credentials Grant (Server Authentication).

As per the documentation, the Content-Type should be set to application/x-www-form-urlencoded in the request headers, and the following values should be sent in the request body:

client_id=[CLIENT_ID]
client_secret=[CLIENT_SECRET]
grant_type=client_credentials
box_subject_type=enterprise
box_subject_id=[ENTERPRISE_ID]

When running this:

function getBoxService() {
  const service = OAuth2.createService('Box')
    .setTokenUrl('https://api.box.com/oauth2/token')
    .setGrantType('client_credentials')
    .setTokenHeaders({
      'Content-Type': 'application/x-www-form-urlencoded'
    })
    .setParam('client_id', BOX_API_CLIENT_ID)
    .setParam('client_secret', BOX_API_CLIENT_SECRET)
    .setParam('grant_type', 'client_credentials')
    .setParam('box_subject_type', 'enterprise')
    .setParam('box_subject_id', BOX_ENTERPRISE_ID)
    .setPropertyStore(PropertiesService.getUserProperties());

  if (!service.hasAccess()) Logger.log(service.getLastError());
}

I get:

Error: Error retrieving token: invalid_grant, Grant credentials are invalid

I have confirmed that the correct Client ID, Client Secret, and Enterprise ID are being provided, and that the App Access Level to App + Enterprise Access (which the documentation lists as a possible cause of this error).

mc-ct commented 2 years ago

@dking12 I've resolved my issue. In my case I'd missed the prerequisite of adding the app as an authorized app in the Box Admin Console Custom Apps Manager.

After doing that, I was able to generate tokens with this library using this:

const service = OAuth2.createService('Box')
    .setTokenUrl('https://api.box.com/oauth2/token')
    .setGrantType('client_credentials')
    .setParam('client_id', BOX_API_CLIENT_ID)
    .setParam('client_secret', BOX_API_CLIENT_SECRET)
    .setParam('box_subject_type', 'enterprise')
    .setParam('box_subject_id', BOX_ENTERPRISE_ID)
    .setPropertyStore(PropertiesService.getUserProperties());