0

I have a react native app and a node js (v16.13.2) backend. I am storing a refresh token in the react native async storage and for every backend call I am sending this refresh token in order grant access or not. This is done in my isAuth middleware in node js.

In summary isAuth function (authService.js file) takes a refresh_token from the react native app, get a new access_token (id_token) with this refresh_token and then I verify this token with the google-auth-library. If payload.email_verified I call next() in the authController.js file.

The following try / catch clause is in my isAuth function:

    try {
        console.log('with refresh token a new access token is retrieved, in order to check if email_verified');
        const OAuth2 = google.auth.OAuth2;
        const oauth2Client = new OAuth2(
            config.CLIENT_ID_GOOGLE, // ClientID
            config.CLIENT_SECRET_GOOGLE, // Client Secret
            "https://www.sagly.at" // Redirect URL
        );
        oauth2Client.setCredentials({
            refresh_token:
            token
        });

        const res = new Promise((resolve, reject) => {
            oauth2Client.getAccessToken((err, token, res) => {
                if (err) {
                    console.log('oauth2Client.getAccessToken get access token error', err); // Handling the errors
                } else {
                    console.log('token, res', token, res);
                    resolve(res);
                }
            });
        });

        const idToken = await res;
        console.log('isAuth google idToken const of await res.data.id_token', idToken);
        const client = new OAuth2Client(config.CLIENT_ID_GOOGLE);
        // https://developers.google.com/identity/sign-in/ios/backend-auth#verify-the-integrity-of-the-id-token
        result = await client.verifyIdToken({
            idToken: idToken.data.id_token,
            audience: config.CLIENT_ID_GOOGLE,
        });
        console.log('isAuth google result const of await client.verifyIdToken({}) response', result);
        const payload = result.getPayload();
        console.log('isAuth google payload const of result.getPayload() response', payload);
        if (payload && payload.email_verified) {
            console.log('next called');
            return 'next';
        }
    } catch (err) {
        console.log(err);
    }

I get the following error in my catch clause:

isAuth errorMessage FetchError: Failed to retrieve verification certificates: request to https://www.googleapis.com/oauth2/v1/certs failed, reason: connect ETIMEDOUT 74.125.193.95:443
     at ClientRequest.<anonymous> (/app/node_modules/node-fetch/lib/index.js:1483:11)
     at ClientRequest.emit (events.js:400:28)
     at ClientRequest.emit (domain.js:475:12)
     at TLSSocket.socketErrorListener (_http_client.js:475:9)
     at TLSSocket.emit (events.js:400:28)
     at TLSSocket.emit (domain.js:475:12)
     at emitErrorNT (internal/streams/destroy.js:106:8)
     at emitErrorCloseNT (internal/streams/destroy.js:74:3)
     at processTicksAndRejections (internal/process/task_queues.js:82:21) {
   type: 'system',
   errno: 'ETIMEDOUT',
   code: 'ETIMEDOUT',
   config: {
     url: 'https://www.googleapis.com/oauth2/v1/certs',
     headers: {
       'User-Agent': 'google-api-nodejs-client/7.10.1',
       'x-goog-api-client': 'gl-node/14.19.0 auth/7.10.1',
       Accept: 'application/json'
     },
     paramsSerializer: [Function: paramsSerializer],
     validateStatus: [Function: validateStatus],
     responseType: 'json',
     method: 'GET'
   }
 }

Can somebody help me what the reason could be for this error? If you need more specific logging or more details I am happy to add those.

Thanks for the efforts.

Those two packages are imported and in use:

const {OAuth2Client} = require("google-auth-library");

const {google} = require("googleapis");

  • https://stackoverflow.com/a/11417375/9408779 - this solved the issue for me for now. –  Mar 14 '22 at 16:15

0 Answers0