Token在获取访问令牌时已经使用了错误

时间:2014-03-29 06:03:57

标签: node.js api oauth-2.0 passport.js freelancer.com-api

我正在尝试设置node.js应用程序以使用OAuth2.0来使用Elance API 我使用passport.js连接到elance api,到目前为止能够正确获取代码。 在使用api方法之前,我需要获取request token using a post request

但是,我正在使用 已使用的代码'错误。 这是我的回调代码

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');
    });
});

我正在使用requestify来执行post请求,并且没有使用临时代码来使用/调用服务器。 这是生成的错误:

... [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."}]})

3 个答案:

答案 0 :(得分:1)

使用Elance实现此功能的正确方法可能是编写strategy。只需使用其中一个发布的Facebook作为模型,或更简单的GitHub。它应该相当简单,并且封装得更好。以下是完整列表:http://passportjs.org/如果您想要探索。更好的是,使这个模块可以重复使用,其他人可以以更标准的方式从中受益。

策略会为您交换令牌的代码。可能是代码被使用的原因,你得到了这个错误。这是标准OAuth2流程的一部分。

答案 1 :(得分:0)

我遇到了同样的问题,并且必须与Elance支持合作才能解决问题。这个错误对我来说是因为来自具有相同API密钥的多个线程/服务器的同一用户的多个同时请求。

在我的情况下,它是一个服务器线程池,正在进行后台工作,我们需要同步登录,所以它只发生一次。多个线程可以重用相同的access_token,只是不申请代码,然后并行访问access_token / refresh_token。

这也可能发生,因为您有多个人/构建服务器运行测试用例,这些测试用例要求代码然后并行访问access_tokens。

答案 2 :(得分:0)

以下是接收令牌似乎至关重要的要点:

  1. 设置正确的内容类型和内容长度值。
  2. 请求应为HTTPS请求。
  3. 方法应该是POST。
  4. 我还安装并使用了Open SSL,以避免因服务器进行非安全调用而导致的任何问题。
  5. 使用Requestify进行的调用每次都失败,即使我设置了上面#1中提到的相同标题信息。如附带的屏幕截图所示,它可以正常使用https请求调用。
  6. 后续查询的JSON响应来自以下代码:

    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();
    });