首页 文章

通过身份验证保护Google Cloud功能http触发器

提问于
浏览
19

我今天按照本指南试用Google Cloud 端功能:https://cloud.google.com/functions/docs/quickstart

我使用HTTP触发器创建了一个函数,并且能够执行POST请求以触发函数写入数据存储区 .

我想知道是否有办法保护这个HTTP endpoints ?目前似乎它将接受来自任何地方/任何人的请求 .

当谷歌搜索时,我看到大多数结果都谈到使用Firebase保护内容 . 但是,我在这里没有使用Firebase服务 .

我的选择是让它打开,希望没有人知道URL endpoints (默默无闻的安全性),或者在函数本身实现我自己的auth检查?

3 回答

  • 0

    在进一步研究之后,并从@ ricka的答案中得到一个提示,我决定使用以授权标头访问令牌形式传入的JWT令牌对我的 Cloud 功能实施身份验证检查 .

    这是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);
        });
      };
    }
    

    我使用 jsonwebtoken 来验证JWT令牌,并使用 jwks-rsa 来检索公钥 . 我使用Auth0,所以 jwks-rsa 伸出到公钥列表来检索它们 .

    然后可以使用 checkAuth 函数来保护 Cloud 功能:

    exports.get = checkAuth(function (req, res) {
        // do things safely here
    });
    

    您可以在我的github回购中看到此更改https://github.com/tnguyen14/functions-datastore/commit/a6b32704f0b0a50cd719df8c1239f993ef74dab6

    可以通过多种方式检索JWT /访问令牌 . 对于Auth0,可以在https://auth0.com/docs/api/authentication#authorize-client找到API文档

    一旦到位,您可以触发 Cloud 功能(如果您使用http触发器启用了您的功能)

    curl -X POST -H "Content-Type: application/json" \
    -H "Authorization: Bearer access-token" \
    -d '{"foo": "bar"}' \
    "https://<cloud-function-endpoint>.cloudfunctions.net/get"
    
  • 7

    目前似乎有两种方法可以保护Google Cloud Function HTTP endpoints .

    1)使用难以猜测的函数名称(例如:my-function-vrf55m6f5Dvkrerytf35)

    2)检查函数本身内的密码/凭证/签名请求(使用 Headers 或参数)

    可能两者都做得最好 .

  • 0

    你不应该"leave it open and hope no one knows" . 您可以实施自己的安全检查,也可以尝试使用Google功能授权模块(https://www.npmjs.com/package/google-function-authorizer) .

相关问题