Created
November 18, 2021 12:42
-
-
Save salrashid123/e5fc03761f62ef6ff213ac3b29661967 to your computer and use it in GitHub Desktop.
node_impersonated_creds with GCS (ref https://github.com/googleapis/google-auth-library-nodejs/issues/1210)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { GoogleAuth, OAuth2Client, Impersonated } = require('google-auth-library'); | |
const { Storage } = require('@google-cloud/storage'); | |
async function main() { | |
const scopes = 'https://www.googleapis.com/auth/cloud-platform' | |
// get source credentials | |
const auth = new GoogleAuth({ | |
scopes: scopes | |
}); | |
const client = await auth.getClient(); | |
// First impersonate | |
let targetPrincipal = '[email protected]' | |
let targetClient = new Impersonated({ | |
sourceClient: client, | |
targetPrincipal: targetPrincipal, | |
lifetime: 30, | |
delegates: [], | |
targetScopes: [scopes] | |
}); | |
let projectId = 'fabled-ray-104117' | |
let bucketName = 'fabled-ray-104117-test' | |
// now construct workaround to use GCS client library | |
const oauth2Client = new OAuth2Client(); | |
oauth2Client.refreshHandler = async () => { | |
const refreshedAccessToken = await targetClient.getAccessToken(); | |
return { | |
access_token: refreshedAccessToken.token, | |
expiry_date: refreshedAccessToken.expirationTime, | |
}; | |
}; | |
// inject the oauth2client into the StorageOptions override | |
// for the access_token and the sign() override as well | |
const storageOptions = { | |
projectId, | |
authClient: { | |
getCredentials: async () => { | |
return { | |
client_email : targetPrincipal | |
} | |
}, | |
request: opts => { | |
return oauth2Client.request(opts); | |
}, | |
sign: (blobToSign) => { | |
return targetClient.sign(blobToSign); | |
}, | |
authorizeRequest: async opts => { | |
opts = opts || {}; | |
const url = opts.url || opts.uri; | |
const headers = await oauth2Client.getRequestHeaders(url); | |
opts.headers = Object.assign(opts.headers || {}, headers); | |
return opts; | |
}, | |
}, | |
}; | |
const storage = new Storage(storageOptions); | |
// use the gcs client to get an object | |
const file = storage.bucket(bucketName).file('foo.txt'); | |
await file.download(function (err, contents) { | |
console.log("file err: " + err); | |
console.log("file data: " + contents); | |
}); | |
// now use the gcs client to sign a url | |
const options = { | |
version: 'v4', | |
action: 'read', | |
expires: Date.now() + 10 * 60 * 1000, | |
}; | |
const [signed_url] = await storage | |
.bucket('fabled-ray-104117-test') | |
.file('foo.txt') | |
.getSignedUrl(options); | |
console.log(signed_url) | |
const authHeaders = await targetClient.getRequestHeaders(); | |
const url = 'https://storage.googleapis.com/storage/v1/b/' + bucketName + '/o/foo.txt' | |
const resp = await targetClient.request({ url }); | |
console.log(resp.data); | |
} | |
main().catch(console.error); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
note, this workaround uses a
sign()
interface that i added in manually herenode_modules/google-auth-library/build/src/auth/impersonated.js