1

The component that I have doing an API call looks like this:

import React from 'react';
import { Button } from 'react-bootstrap';

class Middle extends React.Component {
    handleClick() {
        console.log('this is:', this);
      }
    // This syntax ensures `this` is bound within handleClick.  // Warning: this is *experimental* syntax.  handleClick = () => {    console.log('this is:', this);  }

    async fetchNonce() {
        const response = await fetch("http://localhost:<PORT NUMBER HERE>/path/to/endpoint")
        console.log(response.status)
        const data = await response.json()
        console.log(data)
    }

    render() {
      return (
        <div className="col-md-12 text-center">
            <Button variant='primary' onClick={this.fetchNonce}>
                Click me
            </Button>
        </div>
      );
    }
  }

export default Middle;

The above code works for a simple throw away local node that I'm running for testing purposes. I want to use the above code to, instead of running a local function, reach out to Google Cloud Functions and run one of my Google Cloud Functions instead.

I created a Google Cloud Platform account, and made a simple hello_world type Python "Cloud Function" that just spits out some simple text. I made this function "HTTP" accessible and only able to be called/authenticated by a "Service Account" that I made for the purpose of calling this very function. I generated a key for this "Service Account" and downloaded the json file for the key.

I've seen a lot of tutorials on how to call functions via an authenticated "Service Account" but I'm concerned that a lot of methods might not be secure or following best practices. What is the best practices way to modify the above code to call a Google Cloud Function and authenticate with my "Service Account?"

1 Answers1

1

As mentioned in the thread Ans1 and Ans2:

1. You can set project-wide or per-function permissions outside the function(s), so that only authenticated users can cause the function to fire, even if they try to hit the endpoint. Here's Google Cloud Platform documentation on setting permissions and authenticating users. Note that, as of writing, I believe using this method requires users to use a Google account to authenticate.
2. JWT token passed in in the form of an Authorization header access token. implementation in Node:

    const client = jwksClient({
    cache: true,
    rateLimit: true,
    jwksRequestsPerMinute: 5,
    jwksUri: "https://<auth0-account>.auth0.com/.well-known/jwks.json"}); .

  function verifyToken(token, cb) {
  let decodedToken;
  try {
    decodedToken = jwt.decode(token, {complete: true});
  } catch (e) {
    console.error(e);
    cb(e);
    return;
  }
  client.getSigningKey(decodedToken.header.kid, function (err, key) {
    if (err) {
      console.error(err);
      cb(err);
      return;
    }
    const signingKey = key.publicKey || key.rsaPublicKey;
    jwt.verify(token, signingKey, function (err, decoded) {
      if (err) {
        console.error(err);
        cb(err);
        return
      }
      console.log(decoded);
      cb(null, decoded);
    });
  });
}
function checkAuth (fn) {
  return function (req, res) {
    if (!req.headers || !req.headers.authorization) {
      res.status(401).send('No authorization token found.');
      return;
    }
    const parts = req.headers.authorization.split(' ');
    if (parts.length != 2) {
      res.status(401).send('Bad credential format.');
      return;
    }
    const scheme = parts[0];
    const credentials = parts[1];

    if (!/^Bearer$/i.test(scheme)) {
      res.status(401).send('Bad credential format.');
      return;
    }
    verifyToken(credentials, function (err) {
      if (err) {
        res.status(401).send('Invalid token');
        return;
      }
      fn(req, res);
    });
  };
}


 

Google Cloud Functions now support two types of authentication and authorization: Identity and Access Management (IAM) and OAuth 2.0. Documentation can be found here.

To gather more information about cloud functions with a JWT token passed in in the form of an Authorization header access token, you can refer to the documentation.

Divyani Yadav
  • 1,030
  • 4
  • 9