【问题标题】:How to use OAuth2 with node.js如何在 node.js 中使用 OAuth2
【发布时间】:2019-07-15 20:19:24
【问题描述】:

我想使用 @google-cloud 客户端库将数据插入 BigQuery。
由于我有多个客户并且每个客户都有不同的 IAM 角色,我不能使用这样的服务帐户:

const bigquery = new BigQuery({
                projectId: `myProject`,
                keyFilename: '/Users/services/ssh/myProject-111.json'
            });

我想像这样使用特定于客户端的 oauth2:

const bigquery = new BigQuery({
                projectId: `mydata-1470162410749`,
                token: clientOauth2Token
            });

我收到此错误

过程中出现错误:请求具有无效的身份验证凭据。预期的 OAuth 2 访问令牌、登录 cookie 或其他有效的身份验证凭据。见https://developers.google.com/identity/sign-in/web/devconsole-project。 - 无效的凭据

这是我正在使用的完整 mocha 测试代码:

import BigQuery from '@google-cloud/bigquery';
import {GoogApi} from "../apiManager" //Private code to get Token from client DB

if (!global._babelPolyfill) {
    var a = require("babel-polyfill")
}

describe('Check routing', async () => {

    it('Test stack  ', async (done) => {

        //Fetch client Auth from local Database
        let apiManager = new GoogApi({query: {integrationTest: 'on'}}, {}, (err, httpResults) => {});
        let clientAuth = await apiManager.getGoogleTokensByUserId(`user@company.con`);

        //Replace the 2 value below with real values
        const tableName = "myTest";
        const dataset = "EVALUEX_DEV";

        try {
            const bigquery = new BigQuery({
                projectId: `myProject`,
                token: clientAuth.credentials.access_token
            });
            await bigquery.createDataset(dataset)
                .then(
                    args => {
                        console.log(`Create dataset, result is: ${args}`)
                    })
                .catch(err => {
                    console.log(`Error in the process: ${err.message}`)
                })
        } catch (err) {
            console.log("err", err)
        }
    })
})

这就是我检查令牌时的样子

{
  "domain": null,
  "_events": {},
  "_eventsCount": 0,
  "transporter": {},
  "credentials": {
    "access_token": "My Token",
    "refresh_token": "my Refresh Token"
  },
  "certificateExpiry": null,
  "refreshTokenPromises": [],
  "_clientId": "my Client Id",
  "_clientSecret": "My client secret",
  "redirectUri": "https://s1dg0yjhih.execute-api.us-east-1.amazonaws.com/stage1/goog/saveToken",
  "eagerRefreshThresholdMillis": 300000
}

【问题讨论】:

  • oauth2.tokeninfo 告诉您有关您尝试使用的令牌的哪些信息?
  • @David 我的 oAuth2 是 JSON,我将结构添加到问题中

标签: google-bigquery


【解决方案1】:

您共享的 JSON 对象不是 OAuth 令牌,它看起来像来自 @google-auth-library 的 OAuth2Client 对象。

实际的 OAuth 令牌只是一个字符串,例如“ya29.ABC123ABC123_cG123ABCDETCETCETC”。

那个“令牌”实际上是一个 OAuth2Client,然后您可以使用 getAccessToken 方法获取令牌。如果它只是一个普通的 JSON 对象,那么你可以得到 credentials.access_token 字段,是实际的访问令牌。

请注意,访问令牌会过期。 getAccessToken 会在必要时获取一个新的,但是仅仅从对象中获取 access_token 不会,并且可能在过期后导致 403s。

【讨论】:

  • 谢谢,但即使我尝试 clientAuth.getAccessToken() 或 clientAuth.credentials.access_token 都返回 ya29。像令牌一样,我仍然收到错误消息Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential(我更新了我的原始代码以反映您的代码推荐)
  • 你可以试试oauth2.tokeninfo 看看令牌是否有效?这将告诉我们是正确使用了错误的令牌,还是错误地使用了良好的令牌。
  • 我应该在 id_token(可能是 _clientId 的值?)和 token_handle 中输入什么值。如果我只填写 access_token ya29xxx 我得到“无效值”响应
  • access_token 是正确的字段,其他字段留空。如果显示无效值,则表示访问令牌存在问题。它们在一小时后过期,因此如果您存储访问令牌并在一小时后尝试使用它,它将无法正常工作。如果旧令牌过期,getAccessToken() 应该会获得一个新令牌,所以我很惊讶您在使用它时遇到了同样的问题。
  • 我无法让 @google-cloud/bigquery 在我自己的测试中使用自定义 OAuth 令牌。这个库你可能会更好:developers.google.com/api-client-library/javascript。它使用起来不如自动生成好,也不是特定于云的,但对于边缘情况它可以更灵活一些。
猜你喜欢
  • 2017-08-15
  • 2014-10-11
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 2019-04-29
  • 1970-01-01
  • 2015-04-29
  • 2014-01-10
相关资源
最近更新 更多