如何在没有托管页面的情况下从node-webkit获取桌面应用程序的访问令牌?

时间:2014-06-19 19:04:08

标签: javascript facebook node.js facebook-graph-api node-webkit

我正在尝试使用node-webkit创建桌面应用。此应用程序的一部分需要使用Facebook来获取/发布一些内容到任何在我的个人计算机上使用我的桌面应用程序的个人资料(Facebook用户)。

关于facebook api文档(https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.0),我必须手动实现登录流程并使用以下URI作为重定向URI:https://www.facebook.com/connect/login_success.html

目前,在我的node-webkit应用程序中,通过子窗口(弹出窗口),用户可以登录到Facebook并授权我的桌面应用程序与其配置文件进行交互。 以下是代码的一部分:

var url = "https://www.facebook.com/dialog/oauth?client_id=myclientID&redirect_uri=https://www.facebook.com/connect/login_success.html&response_type=token&scope=publish_actions";
loginWindow = window.open(url, 'Login facebook', 'location=yes,toolbar=yes,menubar=yes,directories=yes,status=yes,resizable=yes,scrollbars=yes,height=480,width=640', false);

之后,用户被重定向到以下URI,并且如文档中所述,访问令牌显示正确:

https://www.facebook.com/connect/login_success.html#access_token=theBigTokenString&expires_in=3864

但它只出现在几秒钟​​之后,然后将网址替换为https://www.facebook.com/connect/blank.html#_=_(带有安全警告消息)。

我已经阅读了一些建议将hashchange之类的eventListener添加到打开的窗口以便捕获访问令牌的帖子。但是在子窗口中进行了一些重定向后,我再也无法通过javascript与它进行交互。

最后,我无法获取子窗口已检索到的访问令牌,并在几秒钟内可见。

是否有人可以帮助我使用node-webkit获取此用户访问令牌? 我真的不想在我的桌面应用程序和Facebook之间使用服务器(用于托管网页)。

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:5)

在另一个问题(here)的帮助下,我找到了解决问题的方法。

我发布了我现在使用的代码,我希望它能帮助别人:

var url = "https://www.facebook.com/dialog/oauth?&client_id=myBigClientID&redirect_uri=https://www.facebook.com/connect/login_success.html&response_type=token&scope=publish_actions";

function Response() {
  this.access_token = null; 
  this.expires_in  = null;
};

var response = new Response();

//function called every 500ms to check if token is in url
window.hashUpdate = function() {
  if(window.loginWindow.closed){
    window.clearInterval(intervalId);
    start(); //just a callback that I'm using to start another part of my application (after I caught the token)
  }
  else {
    var url = window.loginWindow.document.URL;
    var tabUrl = url.split("#"); //first split to separate the domain part and the parameter part
    var paramString = tabUrl[1]; //I concerned only by the second part after the '#'
    if(paramString != undefined){
      var allParam = paramString.split("&");
      for (var i = 0; i < allParam.length; i++) {
        var oneParamKeyValue = allParam[i].split("=");
        response[oneParamKeyValue[0]] = oneParamKeyValue[1]; //store my token in form of key => value
      };

      //close the window after 1500ms
      setTimeout(function(){
        window.loginWindow.close();
      }, 1500);
    }

  }
}

//open the url and start the watching process
window.loginWindow = window.open(this.url, 'Login facebook', false);
this.intervalId = window.setInterval("window.hashUpdate()", 500);