2

This may be a stupid question and I have tried to follow the instructions given from the quire-api-blog but I still have trouble obtaining a token from a Tampermonkey javascript userscript.

FYI syntax for GM_xmlhttpRequest is available on https://www.tampermonkey.net/documentation.php?ext=dhdg#GM_xmlhttpRequest

I am using the following code:

GM_xmlhttpRequest({
    method: "POST",
    url: "https://quire.io/oauth/token",
    data: JSON.stringify({
              grant_type: "authorization_code",
              code: "xxx",
              client_id: ":yyy",
              client_secret: "zzz"
          }),
    onload: function(r){
        console.log(r);
    }
});

This returns in the console the following object:

finalUrl: "https://quire.io/oauth/token"
​
readyState: 4
​
response: 
​
responseHeaders: "content-encoding: gzip\r\ncontent-type: text/plain; charset=utf-8\r\ndate: Sun, 13 Oct 2019 09:04:26 GMT\r\nserver: nginx/1.17.3\r\nset-cookie: DARTSESSID=7d20dcf1f0eae6ce0f69d9fe615e9ce5; Path=/; HttpOnly\r\nx-content-type-options: nosniff\r\nx-firefox-spdy: h2\r\nx-frame-options: SAMEORIGIN\r\nx-xss-protection: 1; mode=block\r\n"
​
responseText: 
​
responseXML: 
​
status: 400
​
statusText: "Bad Request"

Any idea what went wrong?

Thank in advance for your kind answer.

Rafaël

cor3000
  • 936
  • 1
  • 6
  • 16
Rafaël
  • 33
  • 3

2 Answers2

2

You need to be careful on the content-type of your request. Different XHR APIs use different defaults.

The OAUTH2 Specification for the Access Token Request describes the Content-Type to be application/x-www-form-urlencoded.

While GreaseMonkey is sending requests using JSON by default, which can be changed, by setting the Content-Type Header and encoding the data as a String using 'x-www-form-urlcoded'

GM.xmlHttpRequest({
  method: "POST",
  url: "https://quire.io/oauth/token",
  data: "grant_type=authorization_code&code=xxx&client_id=yyy&client_secret=zzz",
  headers: {
    "Content-Type": "application/x-www-form-urlencoded"
  },

jquery.ajax() does this automatically setting the default Content-Type to application/x-www-form-urlencoded

IMPORTANT SIDE NOTE: Your usage of $.ajax() indicates usage in the browser. If that's true then DON'T do it! Exposing your client_secret to an application running inside the browser will allow anyone to authenticate as your quire identity and access your project using the grant_type: client_authentication. As of now the Quire API requires you to run a dedicated server, from which you have to perform the Access Token Request, to avoid exposing the client_secret. If you're using jquery at server side, then that's OK.

There is the open Issue#8 to also support a client side authorization_code flow without using the client_secret (suitable from a SPA or browser extension).

Community
  • 1
  • 1
cor3000
  • 936
  • 1
  • 6
  • 16
  • Thank you very much for your answer, now I get it! Also, I realise I was not encoding properly the data parameter : I should have been using `$.param()`instead of `JSON.stringify()` – Rafaël Oct 19 '19 at 10:46
0

In the meanwhile, for what it's worth, I have been able to make it work with jQuery $.ajax() command, see https://api.jquery.com/jquery.ajax/, which gives:

$.ajax({
    type: "POST",
    url: "https://quire.io/oauth/token",
    data: {
        grant_type: "authorization_code",
        code: "xxx",
        client_id: ":yyy",
        client_secret: "zzz"
    },
    success: function(r){
        console.log(r);
    }
});

Still curious to know from an intellectual point of view what was going wrong with GM_xmlhttpRequest

Rafaël
  • 33
  • 3