Question

I am trying to setup a node.js application to use the Elance API using OAuth2.0 I am using passport.js to connect to the elance api and so far am able to get the code properly. Before using the api methods, I then need to obtain the request token using a post request.

However, I am getting a 'Code Already Used' error. Here's my callback code

app.get('/callback', 
  passport.authenticate('elance', { failureRedirect: '/failure' }),
  function(req, res) {
    console.log('CODE : ' + req.query.code); // this is getting displayed properly
 var payload = {
    code: req.query.code,
    grant_type:'authorization_code',
    client_id: auth.CLIENT_ID,
    client_secret: auth.CLIENT_SECRET
  };

request.post('https://api.elance.com/api2/oauth/token/', payload)
   .then(function(response) {
        var x = response.getBody();
        console.log('resp::::'+x);
        res.redirect('/success');
    });
});

I am using requestify to perform the post request and am not using/calling to the server with the temporary code. Here's the generated error:

... [Sat, 29 Mar 2014 05:54:15 GMT] "GET /callback?code=F9t-zztOLJ3IOlbGXlsqous686HstXqkv7etrvEnF11Vg4M HTTP/1.1" - - "-" "Mozilla/5.0 (X11; Linux i686 on x86_64; rv:30.0) Gecko/20100101 Firefox/30.0"
InternalOAuthError: Failed to obtain access token (status: 401 data: {"errors":[{"code":null,"description":"Code already used."}]})
Was it helpful?

Solution 3

Following are the points which seems to be vital in order to receive the token:

  1. Setting the correct content-type and Content-Length values.
  2. The request should be a HTTPS request.
  3. Method should be POST.
  4. I also installed and used Open SSL, just to avoid any issue caused due to non secure calls made by the server.
  5. Calls made using Requestify were failing each time, even when I set the identical header information mentioned in #1 above. As visible in the attached screenshot, it works fine with normal https request calls.

JSON response from subsequent queries was obtained from the following code:

var request = require("request");
var jobURL = 'https://api.elance.com/api2/jobs/my?access_token=' + _token;

request(jobURL, function (error, response, body) {
    res.write(body);
    res.end();
});

OTHER TIPS

Perhaps the proper way of implementing this with Elance is to write a strategy. Just use one of the other ones published like Facebook as a model, or a simpler one like GitHub. It should be fairly straightforward, and better encapsulated. Here's a complete list: http://passportjs.org/ if you want to explore. Better yet, making this module reusable, others can then benefit from it in a more standard way.

Strategies will exchange the code for the token for you. Likely the reason the code is used and you get that error. That is part of the the standard OAuth2 flow.

I had the same problem, and had to work with Elance support to get it figured out. This error occured for me because multiple simultaneous requests were coming in for the same user from multiple threads/servers with the same API key.

In my case, it was a pool of server threads that were doing background work and we needed to synchronize the login so it only happened once. Multiple threads can re-use the same access_token, just not apply for a code and then an access_token/refresh_token in parallel.

This could also happen because you have multiple people / build servers running test cases which are asking for codes and then access_tokens in parallel.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top