web-dev-qa-db-fra.com

Comment protéger le noeud final Firebase Cloud Function HTTP pour autoriser uniquement les utilisateurs authentifiés Firebase?

Avec la nouvelle fonction cloud de Firebase, j'ai décidé de déplacer certains de mes terminaux HTTP vers Firebase. Tout fonctionne très bien ... Mais j'ai le problème suivant. J'ai deux extrémités construites par des déclencheurs HTTP (fonctions de nuage)

  1. Un point de terminaison API permettant de créer des utilisateurs et renvoyant le jeton personnalisé généré par le SDK d'administration Firebase.
  2. Un point de terminaison API permettant d'extraire certains détails de l'utilisateur.

Bien que le premier point final soit correct, mais pour mon deuxième point final, je voudrais le protéger uniquement pour les utilisateurs authentifiés. ce qui signifie quelqu'un qui a le jeton que j'ai généré plus tôt.

Comment puis-je résoudre ce problème?

Je sais que nous pouvons obtenir les paramètres d'en-tête dans la fonction cloud en utilisant

request.get('x-myheader')

mais existe-t-il un moyen de protéger le système d'extrémité au même titre que la protection de la base de données en temps réel?

88
spaceMonkey

Il y a un officiel exemple de code pour ce que vous essayez de faire. Cela illustre comment configurer votre fonction HTTPS pour exiger un en-tête d'autorisation avec le jeton que le client a reçu lors de l'authentification. La fonction utilise la bibliothèque firebase-admin pour vérifier le jeton.

En outre, vous pouvez utiliser " fonctions appelables " pour faciliter l'utilisation de cette plate-forme, si votre application est capable d'utiliser les bibliothèques clientes Firebase.

88
Doug Stevenson

Comme mentionné par @Doug, vous pouvez utiliser firebase-admin pour vérifier un jeton. J'ai mis en place un exemple rapide:

exports.auth = functions.https.onRequest((req, res) => {
  cors(req, res, () => {
    const tokenId = req.get('Authorization').split('Bearer ')[1];

    return admin.auth().verifyIdToken(tokenId)
      .then((decoded) => res.status(200).send(decoded))
      .catch((err) => res.status(401).send(err));
  });
});

Dans l'exemple ci-dessus, j'ai également activé CORS, mais c'est facultatif. D'abord, vous obtenez l'en-tête Authorization et découvrez le token.

Ensuite, vous pouvez utiliser firebase-admin pour vérifier ce jeton. Vous obtiendrez les informations décodées pour cet utilisateur dans la réponse. Sinon, si le jeton n'est pas valide, une erreur sera générée.

J'espère que ça aide.

76
Will

Comme mentionné également par @Doug, vous pouvez utiliser Fonctions appelables afin de exclure certains codes standard de votre client et de votre serveur.

Fonction appelable Exampale:

export const getData = functions.https.onCall((data, context) => {
  // verify Firebase Auth ID token
  if (!context.auth) {
    return { message: 'Authentication Required!', code: 401 };
  }

  // do your things..
  const uid = context.auth.uid;
  const query = data.query;

  return { message: 'Some Data', code: 400 };
});

Il peut être invoqué directement de votre client comme suit:

firebase.functions().httpsCallable('getData')({query}).then(result => console.log(result));
0
Benny