When doing calls to Exact-on-line API to get authenticated we run into the problem that getting the first refresh-token fails. We're not sure why. This is what we get back from Exact:

  • Http code: 400
  • JSON Data:
{
    error='invalid_request',
    description='Handle could not be extracted',
    uri='null',
    state='null',
    scope='null',
    redirectUri='null',
    responseStatus=400,
    parameters={}
}

We use this Java code based on library org.apache.oltu.oauth2.client (1.0.2):

OAuthClientRequest oAuthRequest = OAuthClientRequest //
        .tokenLocation(BASE_URL + "/api/oauth2/token") //
        .setGrantType(GrantType.AUTHORIZATION_CODE) //
        .setClientId(clientId) //
        .setClientSecret(clientSecret) //
        .setRedirectURI(REDIRECT_URI) //
        .setCode(code) //
        .buildBodyMessage();

OAuthClient client = new OAuthClient(new URLConnectionClient());

OAuthJSONAccessTokenResponse oauthResponse = client.accessToken(oAuthRequest, OAuth.HttpMethod.POST);

We did do the first step (getting the 'code' as used in setCode(...)) using a localhost-redirect as displayed in https://support.exactonline.com/community/s/knowledge-base#All-All-DNO-Content-gettingstarted There we copy the code from the address-bar of our browser and store it in a place the next computer-step can read it again.

1

There are 1 best solutions below

0
On

This is due to the fact that the code was copied from your browsers address-bar. There you will find a URL-encoded version of the code (visible in the '%21' often) which when passed into the setCode verbatim will fail the subsequent calls.

Suggestion: URL-decode the value or setup a small temporary localhost-HTTP-server using Undertow or the like to catch the code that was send to you localhost-URL:

Undertow server = Undertow.builder() //
        .addHttpListener(7891, "localhost") //
        .setHandler(new HttpHandler() {
            @Override
            public void handleRequest(final HttpServerExchange exchange) throws Exception {
                String code = exchange.getQueryParameters().get("code").getFirst();
                LOG.info("Recieved code: {}.", code);
                LOG.info("Store code");
                storeCode(code);
                LOG.info("Code stored");

                exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain");
                exchange.getResponseSender().send( //
                        "Thanks for getting me the code: " + code + "\n" //
                                + "Will store it for you and get the first refreshToken..." //
                                + "Please have a look at " + OAUTH_STATE_INI
                                + " for the new code & refreshToken in a minute" //
                );

                done.add("done");
            }
        }).build();
server.start();

NB: Do make sure the redirect URL is correct in your Exact-app-settings