使用身份验证保护Google Cloud函数http触发 [英] Secure Google Cloud Functions http trigger with auth

查看:278
本文介绍了使用身份验证保护Google Cloud函数http触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

按照本指南,我今天尝试了Google Cloud Functions: https://cloud.google。 com / functions / docs / quickstart



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



我想知道是否有办法保护这个HTTP端点?目前看来,它会接受来自任何地方/任何人的请求。

使用Google搜索时,我发现大多数结果都是关于如何确保Firebase的安全。然而,我并没有在这里使用Firebase服务。



我的选项是让它打开,并且希望没有人知道URL端点(默默无闻的安全性),或者在函数本身中实现我自己的验证检查?

解决方案

在进一步研究之后,从@ ricka的回答中获得提示后,我已决定通过以授权头访问令牌形式传入的JWT令牌来实现对我的云功能的验证检查。



以下是Node中的实现: / p>

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

函数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,decode) {
if(err){
console.error(err);
cb(err);
return
}
console.log(已解码) ;
cb(null,decode);
});
});


函数checkAuth(fn){
返回函数(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];如果(!/ ^ Bearer $ / i.test(scheme)){
res.status(401).send('Bad credential format。');


return;

verifyToken(凭证,函数(err){
if(err){
res.status(401).send('Invalid token');
返回;
}
fn(req,res);
});
};
}

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



checkAuth 函数可以用来保护云功能,如下所示:

  exports .get = checkAuth(function(req,res){
//在这里安全地做事
});

你可以在 https://github.com/tnguyen14/functions-datastore/commit/a6b32704f0b0a50cd719df8c1239f993ef74dab6



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



完成此操作后,您可以触发云端功能(如果您启用了http触发器)
$ b

 curl -X POST -HContent-Type:application / json\ 
-H授权:承载访问令牌\
-d'{foo:bar}'\
https://< cloud-function-endpoint> .cloudfunctions.net / get


I am trying out Google Cloud Functions today following this guide: https://cloud.google.com/functions/docs/quickstart

I created a function with an HTTP trigger, and was able to perform a POST request to trigger a function to write to Datastore.

I was wondering if there's a way I can secure this HTTP endpoint? Currently it seems that it will accept a request from anywhere/anyone.

When googling around, I see most results talk about securing things with Firebase. However, I am not using the Firebase service here.

Would my options be either let it open, and hope no one knows the URL endpoint (security by obscurity), or implement my own auth check in the function itself?

解决方案

After looking into this further, and taking a hint from @ricka's answer, I have decided to implement an authentication check for my cloud functions with a JWT token passed in in the form of an Authorization header access token.

Here's the 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);
    });
  };
}

I use jsonwebtoken to verify the JWT token, and jwks-rsa to retrieve the public key. I use Auth0, so jwks-rsa reaches out to the list of public keys to retrieve them.

The checkAuth function can then be used to safeguard the cloud function as:

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

You can see this change on my github repo at https://github.com/tnguyen14/functions-datastore/commit/a6b32704f0b0a50cd719df8c1239f993ef74dab6

The JWT / access token can be retrieved in a number of way. For Auth0, the API doc can be found at https://auth0.com/docs/api/authentication#authorize-client

Once this is in place, you can trigger the cloud function (if you have yours enabled with http trigger) with something like

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

这篇关于使用身份验证保护Google Cloud函数http触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆