通过node.js使用承载令牌对Google云进行身份验证 [英] google cloud authentication with bearer token via nodejs

查看:225
本文介绍了通过node.js使用承载令牌对Google云进行身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的客户端在Google云运行上运行了GraphQL API.

My client has a GraphQL API running on Google cloud run.

我已经收到一个用于身份验证以及访问gcloud命令行工具的服务帐户.

I have recieved a service account for authentication as well as access to the gcloud command line tool.

像这样使用gcloud命令行时:

When using gcloud command line like so:

gcloud auth print-identity-token

我可以生成一个令牌,该令牌可用于向api发出发布请求.这样可以正常工作,我可以成功地从邮递员,失眠症和我的nodejs应用程序向api发出成功的发布请求.

I can generate a token that can be used to make post requests to the api. This works and I can make successful post requests to the api from postman, insomnia and from my nodejs app.

但是,当我将JWT身份验证与"googleapis"或"google-auth" npm库一起使用时:

However, when I use JWT authentication with "googleapis" or "google-auth" npm libraries like so :

var { google } = require('googleapis')

let privatekey = require('./auth/google/service-account.json')

let jwtClient = new google.auth.JWT(
  privatekey.client_email,
  null,
  privatekey.private_key,
  ['https://www.googleapis.com/auth/cloud-platform']
)

jwtClient.authorize(function(err, _token) {
  if (err) {
    console.log(err)
    return err
  } else {
    console.log('token obj:', _token)
  }
})

这将输出一个"bearer"令牌:

This outputs a "bearer" token:

token obj: {
  access_token: 'ya29.c.Ko8BvQcMD5zU-0raojM_u2FZooWMyhB9Ni0Yv2_dsGdjuIDeL1tftPg0O17uFrdtkCuJrupBBBK2IGfUW0HGtgkYk-DZiS1aKyeY9wpXTwvbinGe9sud0k1POA2vEKiGONRqFBSh9-xms3JhZVdCmpBi5EO5aGjkkJeFI_EBry0E12m2DTm0T_7izJTuGQ9hmyw',
  token_type: 'Bearer',
  expiry_date: 1581954138000,
  id_token: undefined,
  refresh_token: 'jwt-placeholder'
}

但是,该承载令牌不能与上述令牌一起使用,并且在发出与gcloud命令"gcloud auth打印身份令牌"相同的请求时,始终会给出未经授权的错误401".

however this bearer token does not work as the one above and always gives an "unauthorised error 401" when making the same requests as with the gcloud command "gcloud auth print-identity-token".

请帮助,我不确定为什么第一个承载令牌有效,但JWT生成的令牌无效.

Please help, I am not sure why the first bearer token works but the one generated with JWT does not.

我还试图获取身份令牌,而不是像这样的访问令牌:

I have also tried to get an identity token instead of an access token like so :

let privatekey = require('./auth/google/service-account.json')

let jwtClient = new google.auth.JWT(
  privatekey.client_email,
  null,
  privatekey.private_key,
  []
)

jwtClient
  .fetchIdToken('https://my.audience.url')
  .then((res) => console.log('res:', res))
  .catch((err) => console.log('err', err))

这会打印一个身份标记,但是,使用此标记还会给出一条"401未经授权"的消息.

This prints an identity token, however, using this also just gives a "401 unauthorised" message.

请注意,以下任何这些方法都可与命令行标识令牌一起使用,但是当通过JWT生成时,它将返回401

Just a side note, any of these methods below work with the command line identity token, however when generated via JWT, it returns a 401

方法1:

 const client = new GraphQLClient(baseUrl, {
        headers: {
          Authorization: 'Bearer ' + _token.id_token
        }
      })
      const query = `{
        ... my graphql query goes here ...
    }`
      client
        .request(query)
        .then((data) => {
          console.log('result from query:', data)
          res.send({ data })
          return 0
        })
        .catch((err) => {
          res.send({ message: 'error ' + err })
          return 0
        })
    }

方法2(使用我通过google-auth创建的授权"客户端):

Method 2 (using the "authorized" client I have created with google-auth):

  const res = await client.request({
    url: url,
    method: 'post',
    data: `{
        My graphQL query goes here ...
    }`
  })
  console.log(res.data)
}

推荐答案

这里是node.js中的一个示例,该示例正确创建了具有正确受众的身份令牌,以调用Cloud Run或Cloud Functions服务.

Here is an example in node.js that correctly creates an Identity Token with the correct audience for calling a Cloud Run or Cloud Functions service.

修改此示例以适合GraphQLClient.不要忘记在每个调用中都包含Authorization标头.

Modify this example to fit the GraphQLClient. Don't forget to include the Authorization header in each call.

    // This program creates an OIDC Identity Token from a service account
    // and calls an HTTP endpoint with the Identity Token as the authorization
    
    var { google } = require('googleapis')
    const request = require('request')
    
    // The service account JSON key file to use to create the Identity Token
    let privatekey = require('/config/service-account.json')
    
    // The HTTP endpoint to call with an Identity Token for authorization
    // Note: This url is using a custom domain. Do not use the same domain for the audience
    let url = 'https://example.jhanley.dev'
    
    // The audience that this ID token is intended for (example Google Cloud Run service URL)
    // Do not use a custom domain name, use the Assigned by Cloud Run url
    let audience = 'https://example-ylabperdfq-uc.a.run.app'
    
    let jwtClient = new google.auth.JWT(
        privatekey.client_email,
        null,
        privatekey.private_key,
        audience
    )
    
    jwtClient.authorize(function(err, _token) {
        if (err) {
            console.log(err)
            return err
        } else {
            // console.log('token obj:', _token)
    
            request(
                {
                    url: url,
                    headers: {
                        "Authorization": "Bearer " + _token.id_token
                    }
                },
                function(err, response, body) {
                    if (err) {
                        console.log(err)
                        return err
                    } else {
                        // console.log('Response:', response)
                        console.log(body)
                    }
                }
            );
        }
    })

这篇关于通过node.js使用承载令牌对Google云进行身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆