0

I am trying to create a GWT application against the Strava API. The first thing to do is authentication.

On http://strava.github.io/api/v3/oauth/ they say that for the token exchange you have to do something like :

curl -X POST https://www.strava.com/oauth/token \
   -F client_id=5 \
   -F client_secret=7b2946535949ae70f015d696d8ac602830ece412 \
   -F code=75e251e3ff8fff

As far as I know those -F things represent fields in a multiform post ? So I created something like :

   final FormPanel form = new FormPanel();
   container.add(form);
   form.setAction("https://www.strava.com/oauth/token");
   form.setEncoding(FormPanel.ENCODING_MULTIPART);
   form.setMethod(FormPanel.METHOD_POST);

   VerticalPanel panel = new VerticalPanel();
   form.setWidget(panel);
   panel.add(new Hidden("client_id", CLIENT_ID));
   panel.add(new Hidden("client_secret", CLIENT_SECRET));
   panel.add(new Hidden("code", code));

   form.addSubmitCompleteHandler(new FormPanel.SubmitCompleteHandler() 
   {
       @Override
       public void onSubmitComplete(SubmitCompleteEvent event) 
       {
          GWT.log("complete " + event.getResults());
       }
    });

   container.addAttachHandler(new AttachEvent.Handler()
  {

     @Override
     public void onAttachOrDetach(AttachEvent event)
     {
        form.submit();            
     }
  });

Now when I do this I see the following error in Chrome dev tools :

Refused to display 'https://www.strava.com/oauth/token' in a frame because it set 'X-Frame-Options' to 'deny'.
FormPanelImpl.java:117 POST https://www.strava.com/oauth/token net::ERR_BLOCKED_BY_RESPONSE

Now the questions are. Am I correct by creating a form to mimic that curl example ? Has that frame error something to do with GWT using IFRAME stuff ? How do I fix this ?

Knarf
  • 2,077
  • 1
  • 16
  • 24

1 Answers1

0

Strava is setting a header on their response to you that disallows loading it within an iframe (see How to set 'X-Frame-Options' on iframe?). I assume your GWT app is loading this form within one.

On further reading they also describe this process and I see that's where you found your example curl.

Completing the token exchange

If the user accepts the request to share access to their Strava data, Strava will redirect back to redirect_uri with the authorization code. The application must now exchange the temporary authorization code for an access token, using its client ID and client secret.

You may want to look into using the RequestBuilder. You can set your form data by encoding it via URL.encode and with setHeader("Content-Type", "application/x-www-form-urlencodeddata") on the builder. Your callback there can take care of accepting the token for use elsewhere.

Example partially ganked from GWT Server Communication and written in buffer, not tested:

String url = "https://www.strava.com/oauth/token";
RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, URL.encode(url));
builder.setHeader("Content-Type", "application/x-www-form-urlencodeddata");
String data = URL.encodeQueryString("client_id=5&client_secret=7b2946535949ae70f015d696d8ac602830ece412&code=75e251e3ff8fff");
try {
  Request request = builder.sendRequest(data, new RequestCallback() {
    public void onError(Request request, Throwable exception) {
       // Couldn't connect to server (could be timeout, SOP violation, etc.)
    }

    public void onResponseReceived(Request request, Response response) {
      if (200 == response.getStatusCode()) {
          // Process the response in response.getText()
      } else {
        // Handle the error.  Can get the status text from response.getStatusText()
      }
    }
  });
} catch (RequestException e) {
  // Couldn't connect to server

Having not tested this, I'm not sure the above is the appropriate way of sending the request data, so you may need to figure that part out.

We do have an extra wrinkle though:

All developers need to register their application before getting started. A registered application will be assigned a Client ID and Client SECRET. The SECRET should never be shared.

If this is an application meant to be used by the general public, you shouldn't use the above code. You would have to perform this part on your server.

Jon Sampson
  • 1,473
  • 1
  • 21
  • 31