Unable to handle a 401 (OAUTH token expired) response

Hi, my app is requesting data from a web service that requires OAUTH authentication. I have been able to get a OAUTH token, using communications.makeOAuthRequest and I can use that token to fetch data. The reponse I get back is HTTP 200 with a JSON formatted payload. All good so far. 

The token is valid for 2 hrs and when expired, the web service sends back an HTTP 401 (unauthorized) response. When that happens, I need my code to trigger a token_refresh to acquire a new token from the OAUTH server (standard OAUTH stuff), however the makeWebRequest does not accept the 401 repsonse from the web service, instead I get a -400 responseCode in my makewebrequest callback (invalid response body data)

I set responseType => HTTP_RESPONSE_CONTENT_TYPE_JSON for my makewebrequest calls because the data I receive from the service is JSON formatted, so I have to (I think). Now with the 401 response that does not seem to be the case, I am not sure what ends is vilotaing the rules here, either the web service, or CIQ. Here is a screnshot of the HTTP traffic:

 

One solution would be trigger a token_refresh each time I get a -400 response in my callback but Ideally I'd like to be able to read the different error responseCodes that I get from the web service, so that I know what went wrong. Any ideas how I could work around this? 

TIA

/Fredrik  

  • Well HTTP_RESPONSE_CONTENT_TYPE_TEXT_PLAIN would seem to be appropriate except:

    - makeOAuthRequest() still might not like that if it insists that the server returns “text/plain” for the content-type header in this case

    - even if you could use HTTP_RESPONSE_CONTENT_TYPE_TEXT_PLAIN to handle the error case, then you’d have the opposite problem where it would fail in the success case (assuming that the content-type header specifies “json” in that case)

    - even if you could use HTTP_RESPONSE_CONTENT_TYPE_TEXT_PLAIN to handle both the success and error cases, then you’d have the problem that the API wouldn’t automatically convert the response into a dictionary for you, so you’d have to manually do the conversion (if you even have enough memory for the code to do so.)

    Really the problem is that Garmin’s make*Request() functions are unnecessarily inflexible imo.

    Another example of this is that when you do specify that the response is JSON, Garmin actually requires the response to be an object so it can return a dictionary. While I absolutely understand why they do this, it also means that valid JSON such as an array, number, boolean, string or null will be rejected.

  • I have not been able to find any information on others (non-CIQ) clients having any issues with this.  

    Yeah bc nobody else would design a web client with restrictions like CIQ. But if you ask the garmin defenders on the forums, garmin is no better or worse than any other company

  • Thank you for the response, I fully agree with your reasoning. I think the response handling in makewebrequest is overly strict. I have had similar issues before and had to implement a web proxy in between my CIQ client and the web server to convert the response to Garmin's liking. This time I'm not going to do so.

    I'll put up a change request in the bug reports section and hope that can spark a discussion.     

  • implement a web proxy

    Yeah it says a lot that this workaround has come up so many times over the years, and everyone suggests it without batting an eyelash.