Javascript 从Firefox扩展访问Google Drive

Javascript 从Firefox扩展访问Google Drive,javascript,firefox-addon,google-drive-api,xul,Javascript,Firefox Addon,Google Drive Api,Xul,我正在尝试从Firefox扩展访问(CRUD)Google Drive。扩展是用Javascript编码的,但现有的两个Javascript SDK似乎都不适合;客户端SDK希望“窗口”可用,而在扩展中则不是这样,服务器端SDK似乎依赖于特定于节点的功能,因为在通过browserify运行之后,当我将其加载到chrome中时,在节点中工作的脚本不再如此。我是否一直在使用原始的REST调用? 工作的节点脚本如下所示: var google = require('googleapis'); var

我正在尝试从Firefox扩展访问(CRUD)Google Drive。扩展是用Javascript编码的,但现有的两个Javascript SDK似乎都不适合;客户端SDK希望“窗口”可用,而在扩展中则不是这样,服务器端SDK似乎依赖于特定于节点的功能,因为在通过browserify运行之后,当我将其加载到chrome中时,在节点中工作的脚本不再如此。我是否一直在使用原始的REST调用? 工作的节点脚本如下所示:

var google = require('googleapis');
var readlineSync = require('readline-sync');

var CLIENT_ID = '....',
    CLIENT_SECRET = '....',
    REDIRECT_URL = 'urn:ietf:wg:oauth:2.0:oob',
    SCOPE = 'https://www.googleapis.com/auth/drive.file';

var oauth2Client = new google.auth.OAuth2(CLIENT_ID, CLIENT_SECRET, REDIRECT_URL);

var url = oauth2Client.generateAuthUrl({
  access_type: 'offline', // 'online' (default) or 'offline' (gets refresh_token)
  scope: SCOPE // If you only need one scope you can pass it as string
});

var code = readlineSync.question('Auth code? :');

oauth2Client.getToken(code, function(err, tokens) {
  console.log('authenticated?');
  // Now tokens contains an access_token and an optional refresh_token. Save them.
  if(!err) {
    console.log('authenticated');
    oauth2Client.setCredentials(tokens);
  } else {
    console.log('not authenticated');
  }
});
我在此脚本上使用browserify包装节点GDrive SDK:

var Google = new function(){
    this.api = require('googleapis');
    this.clientID = '....';
    this.clientSecret = '....';
    this.redirectURL = 'urn:ietf:wg:oauth:2.0:oob';
    this.scope = 'https://www.googleapis.com/auth/drive.file';
    this.client = new this.api.auth.OAuth2(this.clientID, this.clientSecret, this.redirectURL);
  }
}
单击按钮后使用调用(如果文本字段没有代码,则会启动浏览器以获取代码):

但是这会产生错误
未授权:无效协议:https:

,您可以从这里尝试
window=window | | content |{}

使用JavaScript客户端API,而不是node.js客户端。虽然browserify会让它工作。你将不得不在后者中暴露你的客户秘密。客户端身份验证的流程与服务器端非常不同。指


说了这么多。实现一个基于REST调用的应用程序其实并不难。所有客户端库中的方法都模拟相应的RESTURL。您可以设置一些自己的函数来处理请求和响应,其余的都会有相同的感觉。

但是,根据用例的不同,它也可能是有限感兴趣的

Firefox附带了一个很小的http服务器,只是一个简单的服务器。它包含在测试中,但这不是忽略它的理由

让我们跟着

棘手的部分是设置重定向URI和Javascript源代码。显然正确的设置是
http://localhost
,但如何确保每个用户都有可用的端口80

你不能,除非你能控制你的用户,否则没有一个端口可以保证为每个人工作。考虑到这一点,让我们选择港口49870和祈祷

所以现在重定向URI,Javascript源代码设置为
http://localhost:49870

假设您使用Add-on SDK,请将
quickstart.html
(请记住添加您的客户机ID)保存在扩展的
data
目录中。现在编辑您的
main.js

const self=require(“sdk/self”);
const{Cc,Ci}=require(“chrome”);
const tabs=require(“sdk/tabs”);
const httpd=require(“sdk/test/httpd”);
var quickstart=self.data.load(“quickstart.html”);
var srv=newhttpd.nsHttpServer();
registerPathHandler(“/gdrive”),函数处理程序(请求、响应){
setHeader(“内容类型”,“文本/html;字符集=utf-8”,false);
让converter=Cc[“@mozilla.org/intl/scriptableunicodecoverter”].createInstance(Ci.nsiscriptableunicodecoverter);
converter.charset=“UTF-8”;
write(converter.ConvertFromUnicode(快速启动));
})
srv.启动(49870);
选项卡。打开(“http://localhost:49870/gdrive");
exports.onUnload=函数(原因){
srv.stop(函数(){});
};
请注意,
quickstart.html
不是作为本地文件打开的,它具有
资源:
URI。驱动器API不喜欢这样。在url
http://localhost:49870/gdrive
。不用说,我们可以使用模板或其他任何东西来代替静态html。还有
http://localhost:49870/gdrive
可以使用常规的PageMod编写脚本


我不认为这是真正的解决办法。总比什么都没有强。

@friflaj你试过模仿窗户obj吗
window=window={}
形成一个高层,看起来他们只使用winodw obj来存储全局变量,这就是我现在尝试的。节点版本使用了一种动态模块加载的形式,似乎可以逃避browserify,因此我放弃了这种方式。您尝试过使用iFrame吗?我相信在firefox中,您可以访问“背景脚本”。这基本上是一个无标题的html页面,您的代码可以在该页面上执行。您应该能够在这里生成iFrame。(胡说八道,我以前就这么做过,但想不起来是怎么做的)我想知道这是否有用:我只是想添加一个警告,说明您不应该尝试完全在客户端完成此操作,因为这将涉及(正如您在上面所发布的)在您的加载项的源代码中暴露您的客户端机密(可通过文件系统访问)。这会给附加组件的用户带来安全风险。相反,我会在附加组件可以调用的单独服务器上托管一个小应用程序,它将使用标准OAuth方法(回调URL等)对用户进行身份验证@friflaj感谢您将其标记为正确。上面的代码片段对您有用吗?还是您尝试了本机REST?碰巧我这样做是为了zotero扩展,…zotero附带了一个可维护的http服务器,所以这应该可以工作。我没想到google会接受localhost重定向URI
function authorize() {
  var code = document.getElementById("code").value.trim();

  if (code === '') {
    var url = Google.client.generateAuthUrl({access_type: 'offline', scope: Google.scope});
    var win = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator).getMostRecentWindow('navigator:browser');
    win.gBrowser.selectedTab = win.gBrowser.addTab(url);
  } else {
    Google.client.getToken(code, function(err, tokens) {
      if(!err) {
        Google.client.setCredentials(tokens);
        // store token
        alert('Succesfully authorized');
      } else {
        alert('Not authorized: ' + err); // always ends here
      }
    });
  }
}