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

Requested request format is not supported: application/x-www-form-urlencoded #280

Closed wlim14 closed 3 years ago

wlim14 commented 3 years ago

Code

function getDriveService() {

  return OAuth2.createService('drive')

      .setAuthorizationBaseUrl('...')
      .setTokenUrl('...')

      .setClientId('...')
      .setClientSecret('...')

      .setCallbackFunction('authCallback')
      .setPropertyStore(PropertiesService.getUserProperties())
}

If I am not mistaken the token format should be defaulted to JSON. Does anyone know why am I receiving this error message if that's the case? It has been working for quite some time until today. I tried adding .setTokenFormat(OAuth2.TOKEN_FORMAT.JSON) and it did not seem to work. Thanks!

Error

image

erickoledadevrel commented 3 years ago

The token format defines the expected format of the token data received from the OAuth provider's token endpoint. This error seems to state that the problem is that the OAuth provider expects the parameters sent to the token endpoint to be in JSON, and those are always sent as form urlencoded parameters. Which OAuth provider are you trying to connect to?

wlim14 commented 3 years ago

It is a third party OAuth provider, not one of Google services. Is there any workaround regarding this issue or it is an error caused by the OAuth provider?

erickoledadevrel commented 3 years ago

If you can tell me which provider I can reference their documentation to make sure this is their desired behavior.

As for workarounds, you may be able to use the setTokenPayloadHandler() method to transform the data into a JSON string, and setTokenHeaders() to set the Content-Type header to be JSON. That said, the Content-Type header is usually set by the contentType advanced parameter to UrlFetchApp, so I'm not sure if that will work.

wlim14 commented 3 years ago

Here's the link to the provider's api documentation. https://docs.servicefusion.com/#/docs/documentation-1

I'll try your suggestions on the workaround to see if that works. Thank you!

erickoledadevrel commented 3 years ago

Ya, they seem to have a pretty non-standard OAuth2 flow. The link to the RFC-6749 spec but don't seem to follow it:

The client makes a request to the token endpoint by sending the following parameters using the "application/x-www-form-urlencoded" format ...

Do let me know if that approach works.

wlim14 commented 3 years ago
function getDriveService() {
  return OAuth2.createService('drive')
      .setAuthorizationBaseUrl('...')

      .setClientId('...')
      .setClientSecret('...')

      .setCallbackFunction('authCallback')
      .setPropertyStore(PropertiesService.getUserProperties())

      .setTokenPayloadHandler(tokenHandler)
      .setTokenHeaders({
        "Content-Type": "application/json"
      })
}

function tokenHandler(payload) {
  return JSON.stringify(payload)
}

Your approach worked! Thanks for your help Eric!