【问题标题】:Service Authentication with Google APIs in Nodejs在 Nodejs 中使用 Google API 进行服务身份验证
【发布时间】:2014-06-04 13:40:37
【问题描述】:

我正在尝试将 YouTube 数据 API V3 与 Node 一起使用,以尝试提供经过身份验证的代理来进行视频搜索。由于该服务将在服务器上运行,因此我创建了一个服务帐户。

这会导致下载密钥文件和以下信息:

我对 JWT 有非常基本的了解,但 OAuth2 page 上的服务部分建议您应该使用他们的库之一来完成它,而不是自己实现它。但是,他们没有在 supported libraries 中列出 Node 库。

稍加挖掘,我发现了 Google API Nodejs 客户端:https://github.com/google/google-api-nodejs-client,它声称受 Google 支持,并且开箱即用地支持 OAuth2。

文档非常少,身份验证示例涉及将 URL 打印到终端,然后在浏览器中访问它以生成令牌。我对源代码进行了挖掘,以查看它是否支持 JWT,并且它似乎确实内置了 JWTClient

/**
 * @constructor
 * JWT service account credentials.
 *
 * Retrieve access token using gapitoken.
 *
 * @param {string=} email service account email address.
 * @param {string=} keyFile path to private key file.
 * @param {array=} scopes list of requested scopes.
 * @param {string=} subject impersonated account's email address.
 *
 */
function JWT(email, keyFile, key, scopes, subject) {
  JWT.super_.call(this);
  this.email = email;
  this.subject = subject;
  this.keyFile = keyFile;
  this.key = key;
  this.scopes = scopes;
  this.GAPI = GAPI;
}

构造函数上方的这个文档注释似乎是这里唯一的解释,我仍然不确定如何使用这个函数。

我假设:

  • email 是您的开发者帐户的电子邮件地址
  • keyFile 是私钥的路径
  • key 是私钥吗? (如果是,为什么还要包含路径?)
  • scopes 是您要访问的 API 范围数组
  • subject???

以前有没有人使用过这项服务,或者能够稍微解释一下这里的差异?

作为参考,这必须是服务器端,因为我需要对请求进行自治的身份验证,并且我不能只使用未经身份验证的请求,因为我在 200 个请求(或类似的请求)中超过了我的每日限额.

【问题讨论】:

    标签: node.js api authentication google-api jwt


    【解决方案1】:

    我已经设法拼凑出一个可行的解决方案,所以我会把它留在这里,以供以后遇到类似问题的任何人使用。

    repo 中有一个 JWT 示例,它更详细地展示了如何使用 JWT 对象的构造函数。

    https://github.com/google/google-api-nodejs-client/blob/master/examples/jwt.js

    这是文档注释的略微修改版本。

    /**
     * @constructor
     * JWT service account credentials.
     *
     * Retrieve access token using gapitoken.
     *
     * @param {string=} email service account email address from developer console.
     * @param {string=} keyFile absolute path to private key file.
     * @param {string=} key the contents of the key if you are loading it yourself (optional)
     * @param {array=} scopes list of requested scopes.
     * @param {string=} subject impersonated account's email address (optional).
     *
     */
    

    完成后的代码是这样的

    // Create the JWT client
    var authClient = new googleapis.auth.JWT(email, keypath, key,
      ['https://www.googleapis.com/auth/youtube']);
    
    // Authorize it to produce an access token
    authClient.authorize(function(err, tokens) {
      if(err) throw err;
    
      // Use discovery to get the youtube api
      googleapis.discover('youtube', 'v3')
      .execute(function(err, client) {
    
        // Create a search
        var search = client.youtube.search.list({
          q: '<query string>',
          part: 'snippet',
          maxResults: 50
        });
    
        // Authenticate with current auth client
        search.authClient = authClient;
    
        // Hey presto!
        search.execute(function(err, results) {
          if(err) throw err;
          console.log(results.items);
        });
    
      });
    
    });
    

    这个代码示例是一团糟,但它足以给你的想法。根据示例,您应该能够做到:

    client.youtube.search.list({
     ... 
    })
    .withAuth(authClient)
    .execute(...); 
    

    但由于某种原因,withAuth 方法不存在。花了一些时间来弄清楚它做了什么,据我所知,如果你手动设置 authClient 属性,它可以正常工作,如上所示。

    附带说明,err 参数不是错误,但 POJO 并按上述方式抛出它们实际上不起作用。除非您乐于看到 [Object object] 作为您的调试信息。

    希望该库很快会得到适当的文档关注,这样的问题会得到解决。

    【讨论】:

    • 感谢您的示例。如果我不提供key,我会遇到问题,它将scopes 参数视为keys,然后将范围留空。你只是省略了keys 还是我完全错过了什么?
    • 我在某个阶段遇到了类似的问题,文档似乎建议您可以将明文密钥作为参数传递,或者传递密钥文件的路径。它没有解释虽然和省略两者似乎给我一个错误。我最终通过了这两个参数并且它起作用了(我知道这很糟糕)。
    • authClient = new googleapis.auth.JWT(config.jwt.email, config.jwt.keyPath, config.jwt.key, [https://www.googleapis.com/auth/youtube']);
    【解决方案2】:

    上面的接缝样本已经过时,所以我附上我发现的东西。除了库的智能感知之外,没有好的文档。我在示例中使用 pubsub:

    const {google} = require('googleapis');
    const path = require('path');
    const util = require('util')
    
    
    async function runSample () {
    
      // Create a new JWT client using the key file downloaded from the Google Developer Console
      const authClient = await google.auth.getClient({
        keyFile: path.join(__dirname, 'jwt.keys.json'),
        scopes: 'https://www.googleapis.com/auth/pubsub'
      });
    
      // Obtain a new pubsub client, making sure you pass along the authClient
      const pb = google.pubsub(
        {
            version:'v1',
            auth: authClient
        });
    
      //make a request to list subscriptions
      //the returned object is a axios response object
      const res = await pb.projects.subscriptions.list(
      {
          project: 'projects/my-project'
      });
    
      //return response data
      return res.data;
    }
    
    runSample().then(res =>{
        console.log(util.inspect(res, false, null))
    }).catch(console.error);
    

    【讨论】:

      猜你喜欢
      • 2012-04-23
      • 2019-02-07
      • 2015-08-11
      • 1970-01-01
      • 1970-01-01
      • 2020-02-28
      • 2013-09-23
      • 2019-08-25
      • 2020-04-22
      相关资源
      最近更新 更多