narzero narzero - 1 month ago 8
Ruby Question

Can't get access token for ExactOnline with OAuth

I'm following the OAuth tutorial here to get a access code in order to authenticate my API requests to the online accounting software Exact Online.

However, I'm stuck at step 3, where I use the authorization code returned in step 2 to obtain the access token.

Here's what I'm trying:

require 'httparty'

EXACT_CLIENT_ID = '<REDACTED>'
EXACT_CLIENT_SECRET = '<REDACTED>'
EXACT_SERVER_BASE_URL = 'https://start.exactonline.nl'
EXACT_AUTH_CODE = '<REDACTED>'

response = HTTParty.post("#{EXACT_SERVER_BASE_URL}/api/oauth2/token", headers: {'Content-Type' => 'application/x-www-form-urlencoded'}, query: {code: EXACT_AUTH_CODE, redirect_uri: 'http://<REDACTED>.runscope.net/', grant_type: 'authorization_code', client_id: EXACT_CLIENT_ID, client_secret: EXACT_CLIENT_SECRET})

puts response
# => 'Bad request'

puts response.code
# => 400


I don't understand why this is happening. When looking at the list of response codes here, the code means:


The request could not be understood by the server due to malformed
syntax. The client SHOULD NOT repeat the request without
modifications.


What am I doing wrong?

Update #1:

I've also tried:

response_2 = HTTParty.post("#{EXACT_SERVER_BASE_URL}/api/oauth2/token", :headers => {'Content-Type' => 'application/x-www-form-urlencoded'}, :body => {'code' => EXACT_AUTH_CODE, 'redirect_uri' => 'http://<REDACED>.runscope.net/', 'grant_type' => 'authorization_code', 'client_id' => EXACT_CLIENT_ID, 'client_secret' => EXACT_CLIENT_SECRET})


But the response is the same.

Answer

Even though using the HTTP POST method you're providing the values as query parameters by supplying them to the query: parameter to the .post method. Instead you should provide them in the body: parameter, see: How can I implement this POST request using HTTParty?

Also your syntax re. body: :body should be fixed, so it would look like:

response_2 = HTTParty.post("#{EXACT_SERVER_BASE_URL}/api/oauth2/token", :headers => {'Content-Type' => 'application/x-www-form-urlencoded'}, :body => {'code' => EXACT_AUTH_CODE, 'redirect_uri' => 'http://<REDACED>.runscope.net/', 'grant_type' => 'authorization_code', 'client_id' => EXACT_CLIENT_ID, 'client_secret' => EXACT_CLIENT_SECRET})

Last but not least: the code value is one-time usage only and has a short lifetime; make sure you use a freshly obtained one.

Comments