J'essaie aujourd'hui Google Cloud Functions en suivant ce guide: https://cloud.google.com/functions/docs/quickstart
J'ai créé une fonction avec un déclencheur HTTP et j'ai pu exécuter une demande POST pour déclencher une fonction à écrire dans le magasin de données.
Je me demandais s'il y avait un moyen de sécuriser ce point de terminaison HTTP? Actuellement, il semble qu'il acceptera une demande de n'importe où/de n'importe qui.
En parcourant Google, je vois que la plupart des résultats parlent de sécuriser les choses avec Firebase. Cependant, je n'utilise pas le service Firebase ici.
Mes options seraient-elles soit laissées ouvertes, et j'espère que personne ne connaît le point de terminaison URL (sécurité par obscurité), soit implémenter ma propre vérification d'authentification dans la fonction elle-même?
Après avoir approfondi cela et pris un indice de la réponse de @ ricka, j'ai décidé d'implémenter une vérification d'authentification pour mes fonctions cloud avec un jeton JWT transmis sous la forme d'un jeton d'accès d'en-tête d'autorisation.
Voici l'implémentation dans 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);
});
};
}
J'utilise jsonwebtoken
pour vérifier le jeton JWT et jwks-rsa
pour récupérer la clé publique. J'utilise Auth0, donc jwks-rsa
atteint la liste des clés publiques pour les récupérer.
La fonction checkAuth
peut alors être utilisée pour sauvegarder la fonction cloud comme:
exports.get = checkAuth(function (req, res) {
// do things safely here
});
Vous pouvez voir ce changement sur mon dépôt github à https://github.com/tnguyen14/functions-datastore/commit/a6b32704f0b0a50cd719df8c1239f993ef74dab6
Le jeton JWT/access peut être récupéré de différentes manières. Pour Auth0, le document API peut être trouvé à https://auth0.com/docs/api/authentication#authorize-client
Une fois que cela est en place, vous pouvez déclencher la fonction cloud (si la vôtre est activée avec le déclencheur http) avec quelque chose comme
curl -X POST -H "Content-Type: application/json" \
-H "Authorization: Bearer access-token" \
-d '{"foo": "bar"}' \
"https://<cloud-function-endpoint>.cloudfunctions.net/get"
Il semble qu'il existe actuellement 2 façons de sécuriser un point de terminaison HTTP Google Cloud Function.
1) Utilisez un nom de fonction difficile à deviner (ex: my-function-vrf55m6f5Dvkrerytf35)
2) Vérifiez le mot de passe/les informations d'identification/la demande signée dans la fonction elle-même (en utilisant un en-tête ou un paramètre)
Il vaut probablement mieux faire les deux.
Vous pouvez créer un algorithme d'authentification personnalisé pour vérifier le client.
Découvrez l'algorithme de; https://security.stackexchange.com/q/210085/22239
Vous ne devez pas "le laisser ouvert et espérer que personne ne le sait". Vous pouvez implémenter votre propre contrôle de sécurité ou vous pouvez essayer le module Google Function Authorizer ( https://www.npmjs.com/package/google-function-authorizer ).