My client has a GraphQL API running on Google cloud run.
I have recieved a service account for authentication as well as access to the gcloud command line tool.
When using gcloud command line like so:
gcloud auth print-identity-token
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.
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)
}
})
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'
}
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".
Please help, I am not sure why the first bearer token works but the one generated with JWT does not.
EDIT
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))
This prints an identity token, however, using this also just gives a "401 unauthorised" message.
Edit to show how I am calling the endpoint
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
Method 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
})
}
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)
}
Assigned by Cloud Run
URL that looks like this:https://example-ylyxpergiq-uc.a.run.app
that you can copy from the Google Cloud Console. Your first example will never work as it generates an Access Token. Your second example is creating the correct type of token which is an Identity Token. – John Hanley