来自第三方API的回调未获得MeteorJS中的当前用户

时间:2016-12-24 01:58:54

标签: javascript asynchronous meteor oauth callback

我通过OAuth连接到第三方API,Intuit Quickbooks,以获取用户的凭据。我已根据需要实现了回调,并且可以成功获取凭据。在回调中,我调用了一个meteor方法函数来使用作为参数传入的凭据更新当前登录用户的配置文件。但是,Meteor无法找到用户。

我尝试过使用Meteor.Async和BindEnvironment,但我遇到了同样的问题。当API返回回调时,是否可以知道哪个用户向第三方API发起了请求?

var stuff;

Router.route('/requestToken', { name: 'requestoken', where: 'server' })
.get(function (req,res) {
  var QuickBooks = require('node-quickbooks');
  var request = require('request');
  var qs = require('querystring');
  var consumerKey    = 'xxxxx',
  consumerSecret = 'xxxxx'

  var postBody = {
    url: QuickBooks.REQUEST_TOKEN_URL,
    oauth: {
      callback:        'http://localhost:3000/callback/',
      consumer_key:    consumerKey,
      consumer_secret: consumerSecret
    }
  }
  console.log('abt to request')
  request.post(postBody, function (e, r, data) {
    var requestToken = qs.parse(data)
    stuff = requestToken.oauth_token_secret;
    console.log(requestToken)
    res.writeHead(301, {
      'Location': QuickBooks.APP_CENTER_URL + requestToken.oauth_token
    });
    res.end();
  })
})
.post(function () {
  // POST 
})
.put(function () {
  // PUT 
})



Router.route('/callback', { name:'callback' , where: 'server' })
.get(function () {
  var req = this.request;
  var res = this.response;

  var QuickBooks = require('node-quickbooks');
  var request = require('request');
  var qs = require('querystring');

  var consumerKey    = 'xxxxx',
  consumerSecret = 'xxxxx'

  var postBody = {
    url: QuickBooks.ACCESS_TOKEN_URL,
    oauth: {
      consumer_key:    consumerKey,
      consumer_secret: consumerSecret,
      token:           req.query.oauth_token,
      token_secret:    stuff,
      verifier:        req.query.oauth_verifier,
      realmId:         req.query.realmId
    }
  }

  request.post(postBody, Meteor.bindEnvironment(function (e, r, data) {
    var accessToken = qs.parse(data)
      qbo = new QuickBooks(consumerKey,
        consumerSecret,
        accessToken.oauth_token,
        accessToken.oauth_token_secret,
        postBody.oauth.realmId,
        true, // use the Sandbox
        true); // turn debugging on
      // test out account access
      qbo.findAccounts(function(_, accounts) {
        accounts.QueryResponse.Account.forEach(function(account) {
          console.log(account.Name)
        })
      });
      // save the access token somewhere on behalf of the logged in user
      var userCred = {
        token:accessToken.oauth_token,
        secret:accessToken.oauth_token_secret,
        real:postBody.oauth.realmId
      }
      console.log("about to call addQB details");
      console.log(userCred);
      //this method simply adds the userCred to the current logged in user's profile.
      //Whenever the method below is called from here, it never finds the user. However when called from the client it works well. 
      //Is it possibe to know logged user from a 3rd party API callback? / How can I go about this?
      Meteor.call("addUserQb",userCred); 
    }));

    res.end('<!DOCTYPE html><html lang="en"><head></head><body><script>window.opener.location.reload(); window.close();</script></body></html>')

  })
  .post(function () {
    // POST 
  })
  .put(function () {
    // PUT 
  })

方法如下。 (当从客户端使用假凭证obj作为参数调用时,该方法很有效。但是在上面的路由器中从回调调用时不会获得用户)

addUserQb:function(obj){
    Meteor.users.update(Meteor.userId(), {
      $set:{
        'profile.token': obj.token,
        'profile.secret': obj.secret,
        'profile.realmId' : obj.real
      }
    } );
}

1 个答案:

答案 0 :(得分:1)

考虑一下这里发生了什么:服务器本身没有userId。从客户端调用的方法是通过DDP协议调用的,DDP协议是由客户端创建并与userId关联的持久连接,因此这些方法确实在其上下文中获得了userId。

来自路由器设置的路径的http请求与任何DDP会话都没有关联,也不能有userId。 bindEnvironment()在这里没有帮助,它只适用于与最初通过DDP调用的方法相关联的nodejs光纤中运行的回调函数

您有来自其他服务器的回调 http请求。这是通过不同的路由进行的,与将原始请求发送给Oauth提供程序的服务器方法没有任何关联。

解决方案:您需要将userId信息添加到Quickbooks的请求中,可能在回调URL中,这样当Quickbooks Oauth服务器进行回调时,您可以从请求中提取userId。