I am trying to create a Fitbit app and to do so I altered an example Twitter Oauth app to get the data from fitbit. The problem I am running into now is that randomly I will get the following error:
12-08 18:36:46.274: W/DefaultRequestDirector(439): Authentication error: Unable to respond to any of these challenges: {oauth=WWW-Authenticate: OAuth realm="http%3A%2F%2Fapp4int.fitbit.com", oauth_problem="nonce_used"}
12-08 18:36:46.284: W/System.err(439): org.apache.http.client.HttpResponseException: Unauthorized
12-08 18:36:46.294: W/System.err(439): at org.apache.http.impl.client.BasicResponseHandler.handleResponse(BasicResponseHandler.java:71)
12-08 18:36:46.294: W/System.err(439): at org.apache.http.impl.client.BasicResponseHandler.handleResponse(BasicResponseHandler.java:59)
12-08 18:36:46.294: W/System.err(439): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:657)
12-08 18:36:46.294: W/System.err(439): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:627)
12-08 18:36:46.294: W/System.err(439): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:616)
12-08 18:36:46.305: W/System.err(439): at org.knoesis.healthcare.HealthcareAppActivity$GetCredentialsTask.doInBackground(HealthcareAppActivity.java:149)
12-08 18:36:46.305: W/System.err(439): at org.knoesis.healthcare.HealthcareAppActivity$GetCredentialsTask.doInBackground(HealthcareAppActivity.java:1)
12-08 18:36:46.305: W/System.err(439): at android.os.AsyncTask$2.call(AsyncTask.java:185)
12-08 18:36:46.305: W/System.err(439): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
12-08 18:36:46.334: W/System.err(439): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
12-08 18:36:46.444: W/System.err(439): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
12-08 18:36:46.444: W/System.err(439): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
12-08 18:36:46.444: W/System.err(439): at java.lang.Thread.run(Thread.java:1096)
Which the interesting part of that is the ‘oauth_problem=”nonce_used”‘ which I researched and it says “nonce_used: the oauth_nonce value was used in a previous request, and consequently can’t be used now.” Which value is the oauth_nonce value and how do I get a new one to use?
Let me know if posting the code in question here would be beneficial.
An OAuth nonce is used to prevent playback attacks by making sure that each valid request you make can only be accepted once.
It’s been a while since I messed with OAuth, but I think you just need to include a randomly-generated string (I think I used the system clock time concatenated onto the requested username and MD5 hashed the result) as the nonce for each request you make. Obviously, this needs to be incorporated into your signature generation code.