205 votes

Comment protéger le point de terminaison HTTP de Firebase Cloud Function pour n'autoriser que les utilisateurs authentifiés par Firebase ?

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

  1. Un endpoint API pour créer des utilisateurs et retourner le Token personnalisé généré par Firebase Admin SDK.
  2. Un point de terminaison de l'API pour récupérer certains détails de l'utilisateur.

Le premier point d'accès est parfait, mais pour mon deuxième point d'accès, je voudrais le protéger uniquement pour les utilisateurs authentifiés, c'est-à-dire ceux qui possèdent le jeton que j'ai généré précédemment.

Comment dois-je m'y prendre pour résoudre ce problème ?

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

request.get('x-myheader')

mais existe-t-il un moyen de protéger le point de terminaison comme on protège la base de données en temps réel ?

0 votes

Comment avez-vous obtenu le jeton personnalisé généré par Firebase Admin SDK dans la première API ?

2 votes

@AmineHarbaoui J'avais la même question. Voir cette page : firebase.google.com/docs/auth/admin/verify-id-tokens

201voto

Doug Stevenson Points 6978

Il y a un officiel exemple de code pour ce que vous essayez de faire. Il illustre comment configurer votre fonction HTTPS pour exiger un en-tête Authorization 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.

Vous pouvez également utiliser " fonctions appelables "Il est possible de simplifier une grande partie de cette procédure, si votre application est en mesure d'utiliser les bibliothèques client de Firebase.

4 votes

Cet exemple de code est-il toujours valable ? Est-ce que c'est toujours la façon dont vous traiteriez cette question aujourd'hui ?

1 votes

@GalBracha Il devrait être encore valable aujourd'hui (31 octobre 2017).

0 votes

@DougStevenson Ces appels à "console.log" auront-ils un impact "notable" sur les performances ?

178voto

Will Points 868

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 le Authorization et trouver l'en-tête 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.

24 votes

Upvoted car il est simple, et ne dépend pas d'express comme le fait l'exemple officiel.

5 votes

Pouvez-vous nous en dire plus sur les cors ?

0 votes

@pete : cors est juste une solution pour le partage des ressources entre origines. Vous pouvez chercher sur Google pour en savoir plus.

50voto

Benny Points 381

Comme l'a également mentionné @Doug, vous pouvez utiliser Fonctions appelables afin de exclure certains codes passe-partout de votre client et de votre serveur.

Exemple de fonction appelable :

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 depuis votre client comme suit :

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

11voto

ultraGentle Points 2552

Les méthodes ci-dessus authentifient l'utilisateur en utilisant la logique à l'intérieur de la fonction, donc la fonction doit toujours être invoquée pour effectuer la vérification.

C'est une méthode tout à fait acceptable, mais dans un souci d'exhaustivité, il existe une alternative :

Vous pouvez définir une fonction comme étant "privée" de sorte qu'elle ne peut pas ne peut être invoqué que par les utilisateurs enregistrés (vous décidez des permissions). Dans ce cas, les demandes non authentifiées sont refusées en dehors du contexte de la fonction, et la fonction est pas invoqué du tout.

Voici les références à (a) Configuration des fonctions comme publiques/privées et ensuite (b) l'authentification des utilisateurs finaux à vos fonctions .

Notez que les documents ci-dessus sont pour Google Cloud Platform, et en effet, cela fonctionne car chaque projet Firebase est également un projet BPC. Cette méthode présente un inconvénient : à l'heure actuelle, elle ne fonctionne qu'avec une authentification basée sur un compte Google.

1 votes

Malheureusement, Firebase ne semble toujours pas prendre en charge cette fonction OOTB pour les utilisateurs de Firebase - si l'on passe un jeton d'authentification, c'est bien ; mais sinon, la fonction est tout de même invoquée :(

0 votes

Donc, en gros, si on enlève le Allow unauthenticated en retirant le allUsers nous ne pouvons pas utiliser une fonction appelable ( onCall ) ? Je ne pense pas que laisser les fonctions publiques soit idéal, il doit y avoir un moyen de paramétrer les fonctions pour qu'elles soient appelables depuis des comptes de service spécifiques. @JanakaBandara

3voto

Antonio Ooi Points 50

Dans Firebase, afin de simplifier votre code et votre travail, il suffit de conception architecturale :

  1. Pour les sites/contenus accessibles au public utiliser Les déclencheurs HTTPS avec Express . Pour restreindre uniquement les sites identiques ou site spécifique uniquement utiliser CORS pour contrôler cet aspect de la sécurité. Cela a du sens car Express est utile pour le référencement en raison de son contenu de rendu côté serveur.
  2. Pour les applications qui nécessitent une authentification de l'utilisateur utiliser Fonctions Firebase appelables par HTTPS puis utilisez le context pour vous épargner tous les tracas. Cela a également du sens, parce que, comme une application à page unique construite avec AngularJS, AngularJS est mauvais pour le référencement, mais comme il s'agit d'une application protégée par un mot de passe, vous n'avez pas besoin du référencement non plus. En ce qui concerne les modèles, AngularJS dispose d'un modèle intégré, donc pas besoin de modèle côté serveur avec Express . Alors Firebase Callable Functions devrait suffire.

En gardant à l'esprit ce qui précède, mettez fin aux tracas et simplifiez-vous la vie.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X