google-auth-library-nodejs icon indicating copy to clipboard operation
google-auth-library-nodejs copied to clipboard

Browser support for getDefaultServiceProjectId

Open cdelguercio opened this issue 3 years ago • 2 comments

I have a project where I use a GCP pubsub client in the browser and my usage of the nodejs-pubsub eventually leads to a call to getDefaultServiceProjectId(), which obviously fails on a browser.

I use a hack where I simply replace:

build/src/auth/googleauth.js

/**
 * Run the Google Cloud SDK command that prints the default project ID
 */
async getDefaultServiceProjectId() {
    return new Promise(resolve => {
        child_process_1.exec('gcloud config config-helper --format json', (err, stdout) => {
            if (!err && stdout) {
                try {
                    const projectId = JSON.parse(stdout).configuration.properties.core.project;
                    resolve(projectId);
                    return;
                }
                catch (e) {
                    // ignore errors
                }
            }
            resolve(null);
        });
    });
}

with

/**
 * Run the Google Cloud SDK command that prints the default project ID
 */
async getDefaultServiceProjectId() {
    return new Promise(resolve => {
        resolve("my-project-id");
    });
}

but I'd rather do something either in Webpack or with a change to this library. I understand that I could resolve the child_process module in Webpack to false or something else, but that seems like the wrong fix in this case since I actually do need the projectId to be resolved for my code to work. I feel like this function is very side-effect-y with its call to exec, so I was wondering if y'all think that there's a good argument to be made for refactoring how the projectId is retrieved and then providing some way to inject/configure a custom projectId at runtime.

cdelguercio avatar Oct 21 '21 21:10 cdelguercio

@cdelguercio thank you for the bug report.

bcoe avatar Oct 22 '21 15:10 bcoe

@cdelguercio I agree that the call to exec is pretty side-effect-y, and it would be worth figuring out an approach that works better in the browser.

We're currently investigating making our libraries work better in browser context. For the time being, I think your best bet is to use WebPack to replace child_process, but we will make sure to address this issue when/if we offer support for our SDK in the browser.

bcoe avatar Apr 11 '22 19:04 bcoe

I understand that I could resolve the child_process module in Webpack to false or something else, but that seems like the wrong fix in this case since I actually do need the projectId to be resolved for my code to work. I feel like this function is very side-effect-y with its call to exec, so I was wondering if y'all think that there's a good argument to be made for refactoring how the projectId is retrieved and then providing some way to inject/configure a custom projectId at runtime.

Hey @cdelguercio, it is possible, and recommended, to pass the projectID to GoogleAuth in its construction at runtime when it would otherwise not be available. In this flow the exec would never be called:

https://github.com/googleapis/google-auth-library-nodejs/blob/6543e0f3da95dcf5aa4e6fc4155757a1a6c32a46/src/auth/googleauth.ts#L120-L123

https://github.com/googleapis/google-auth-library-nodejs/blob/6543e0f3da95dcf5aa4e6fc4155757a1a6c32a46/src/auth/googleauth.ts#L176-L185

PubSub and others also accept projectId as an option during their client construction, which is passed to GoogleAuth:

https://github.com/googleapis/nodejs-pubsub/blob/86c8987ef622d7eed7103d3eada75bbae53b2dbc/src/pubsub.ts#L310

danielbankhead avatar Sep 07 '23 20:09 danielbankhead