web-dev-qa-db-fra.com

Authentification Firebase vs AWS Cognito

Nous construisons une application mobile et Web sur AWS à l'aide d'API Gateway et de Lambda et évaluons actuellement si nous devons utiliser tous les services mobiles AWS (Cognito, Analytics, Mobile Hub, etc.) ou si nous devons utiliser Firebase à la place (ce qui offre certains avantages comme la configuration à distance).

Je pense que l'utilisation de la partie non fonctionnelle de Firebase comme Analytics, Remote Config, Crash Reports, Notification devrait convenir au backend AWS. La partie où je ne suis pas certain est la couche d'authentification.

AWS Cognito s'intègre parfaitement dans API Gateway et Lamdba, par ex. seuls les utilisateurs authentifiés peuvent exécuter certains appels d'API.

Le même comportement peut-il être atteint si nous utilisons plutôt l'authentification Firebase? Une bonne ou une mauvaise expérience avec ça?

35
Tomas

nous faisons de même. Nous avons commencé avec Cognito mais nous sommes passés à Firebase car nous n'étions pas satisfaits de la façon dont AWS Android SDK implémente le flux d'authentification avec Google et Facebook: le code est assez ancien, il utilise des méthodes obsolètes et nécessite généralement une réécriture. D'autre part, l'authentification Firebase fonctionne de manière transparente. Lorsque vous n'utilisez pas Cognito, vous devez implémenter votre authentificateur personnalisé dans AWS API Gateway, ce qui est assez simple et est décrit dans https://aws.Amazon.com/blogs/mobile/integrating-Amazon-cognito-user-pools-with-api-gateway/ . Les instructions Firebase pour la validation des jetons sont en https://firebase.google. com/docs/auth/admin/verify-id-tokens

Ce qui suit est un extrait du code de mon authentificateur:

'use strict';

// Firebase initialization
// console.log('Loading function');
const admin = require("firebase-admin");
admin.initializeApp({
  credential: admin.credential.cert("xxx.json"),
  databaseURL: "https://xxx.firebaseio.com"
});
// Standard AWS AuthPolicy - don't touch !!
...
// END Standard AWS AuthPolicy - don't touch !!

exports.handler = (event, context, callback) => {
    // console.log('Client token:', event.authorizationToken);
    // console.log('Method ARN:', event.methodArn);

    // validate the incoming token
    // and produce the principal user identifier associated with the token

    // this is accomplished by Firebase Admin
    admin.auth().verifyIdToken(event.authorizationToken)
        .then(function(decodedToken) {
            let principalId = decodedToken.uid;
            // console.log(JSON.stringify(decodedToken));

            // if the token is valid, a policy must be generated which will allow or deny access to the client

            // if access is denied, the client will recieve a 403 Access Denied response
            // if access is allowed, API Gateway will proceed with the backend integration configured on the method that was called

            // build apiOptions for the AuthPolicy
            const apiOptions = {};
            const tmp = event.methodArn.split(':');
            const apiGatewayArnTmp = tmp[5].split('/');
            const awsAccountId = tmp[4];
            apiOptions.region = tmp[3];
            apiOptions.restApiId = apiGatewayArnTmp[0];
            apiOptions.stage = apiGatewayArnTmp[1];

            const method = apiGatewayArnTmp[2];
            let resource = '/'; // root resource
            if (apiGatewayArnTmp[3]) {
                resource += apiGatewayArnTmp[3];
            }


            // this function must generate a policy that is associated with the recognized principal user identifier.
            // depending on your use case, you might store policies in a DB, or generate them on the fly

            // keep in mind, the policy is cached for 5 minutes by default (TTL is configurable in the authorizer)
            // and will apply to subsequent calls to any method/resource in the RestApi
            // made with the same token

            // the policy below grants access to all resources in the RestApi
            const policy = new AuthPolicy(principalId, awsAccountId, apiOptions);
            policy.allowAllMethods();
            // policy.denyAllMethods();
            // policy.allowMethod(AuthPolicy.HttpVerb.GET, "/users/username");

            // finally, build the policy and exit the function
            callback(null, policy.build());
            })
        .catch(function(error) {
            // Firebase throws an error when the token is not valid
            // you can send a 401 Unauthorized response to the client by failing like so:
            console.error(error);
            callback("Unauthorized");
        });
};

Nous ne sommes pas encore en production, mais les tests sur l'authentificateur montrent qu'il se comporte correctement avec Google, Facebook et l'authentification par mot de passe et il est également très rapide (60 - 200 ms). Le seul inconvénient que je peux voir est que vous serez facturé pour la fonction authentificateur lambda, tandis que l'authentificateur intégré Cognito est gratuit.

30
pmosconi

TL; DR; Firebase> Cognito

Nous avons d'abord commencé avec Cognito, mais nous avons finalement réalisé qu'il dégageait une odeur atroce lorsqu'il s'agissait d'utiliser des identités fédérées (par exemple, connexion Google, connexion Facebook, etc.). Pour les pools d'utilisateurs Cognito (c'est-à-dire permettre à un utilisateur de s'inscrire/se connecter avec un nom d'utilisateur et un mot de passe), vous pouvez utiliser l'API Gateway Cognito User Pool Authorizer intégré et cela fonctionne à merveille. Vous n'avez pas besoin d'écrire votre propre autorisation personnalisée ou quoi que ce soit.

Cependant, si vous souhaitez prendre en charge les identités fédérées, vous devez remplacer l'authentification de votre passerelle API par IAM Auth, puis demander à CHAQUE client sigv4 de signer les demandes, ce qui s'est avéré être une épine de notre côté et a coûté un temps de développement important. L'option 2 était d'avoir API Gateway pour générer votre code pour vos appels API pour chaque client ... ce qui, à mon avis, témoigne de la lourdeur de l'intégration avec Cognito.

Nous avons fait fonctionner Firebase via l'autoriseur personnalisé pour API Gateway. Était un jeu d'enfant sur tous les clients (iOS, Android et Web). Les points de terminaison de la passerelle API étaient liés aux fonctions Lambda, qui pouvaient communiquer avec DynamoDB, S3 et d'autres services Web pour le compte de l'utilisateur appelant le noeud final. Les fonctions lambda savaient qui était l'appelant, car l'autoriseur personnalisé a renvoyé l'adresse e-mail dans le JWT.

Voici un autoriseur personnalisé Firebase assez basique qui renvoie l'e-mail de l'utilisateur dans le JWT en tant que principalId:

'use strict';
console.log('Loading function');

var admin = require('firebase-admin');
var serviceAccount = require('./my-secret-json.json');

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: 'https://my-app.firebaseio.com'
});

exports.handler = (event, context, callback) => {
    var token = event.authorizationToken;

    if (token == null) {
        callback('Invalid token');
    }
    else {
        admin.auth().verifyIdToken(token)
            .then(function (decodedToken) {
                var email = decodedToken.email;
                var policy = generatePolicy(email);
                callback(null, policy);
            }).catch(function (error) {
                console.log(error);
                callback('Unauthorized'); 
            });
    }
};

var generatePolicy = function (email) {
    return {
        principalId: email,
        policyDocument: {
            Version: '2012-10-17',
            Statement: [
                {
                    Action: 'execute-api:Invoke',
                    Effect: email ? 'allow' : 'deny',
                    Resource: '*'
                }
            ]
        }
    };
}

Vous pouvez ensuite utiliser $context.authorizer.principalId dans votre modèle de mappage API Gateway pour récupérer l'e-mail et le transmettre à lambda X.

19
Aziz Javed

La documentation d'AWS est assez confuse. Le système de rappels pour les différentes étapes d'authentification est mieux documenté dans Firebase. Le résultat est un code plus propre et un meilleur contrôle sur le flux d'authentification. De plus, l'interface utilisateur de Firebase est plus conviviale. Si vous prévoyez d'utiliser des fournisseurs de contenu et des adaptateurs de synchronisation, je vous suggère d'utiliser Firebase car vous disposerez de méthodes simples pour la synchronisation des données entre la base de données locale et distante (Firebase)

5
Nicola Gallazzi

aws cognito offre plus de moyens d'authentifier les utilisateurs que Firebase. Surtout, si vous créez un jeu, il vous permet de vous connecter via les centres de jeux google et ios. Il fournit la synchronisation des classements et les réalisations du Game Center. La fonction de synchronisation automatique des états est présente dans Cognito. Mais définitivement, c'est très déroutant. La mise en œuvre prend trop de temps. D'un autre côté, l'authentification Firebase est assez rapide à implémenter.

2
sn.anurag

Au cas où vous utilisez Unity, le SDK Unity ne prend actuellement pas en charge Cognito User Pool. (Autrement dit, liste d'utilisateurs hébergés par AWS). J'hésite actuellement à cause de cela. Voir mon article ici qu'ils ont confirmé que c'est vrai, actuellement (26/06/2017) la fonctionnalité n'est toujours pas disponible, ce qui pourrait montrer un manque d'attention de la part des utilisateurs d'Unity.

Cependant, si j'utilise Firebase pour les connexions, j'aurais besoin de plus d'intégrations pour que ces informations d'identification utilisent les services AWS. (Je voudrais utiliser S3 et DynamoDB mais seuls les utilisateurs connectés peuvent l'utiliser.) Cela m'a également fait réaliser que je devrais tout déplacer vers Firebase pour économiser mon temps et mes frustrations dès que possible. (La base de données en temps réel est plus chère que S3/DynamoDB, mais Unity a son propre remplacement d'AWS MobileAnalytics)

AWS S3 a récemment amélioré l'interface utilisateur, ce qui, je pense, est proche du niveau de Google. Mais à part cela, je pense que l'interface utilisateur de Firebase est beaucoup plus agréable à utiliser.

De plus, l'authentification Firebase est gratuite tandis que Cognito est gratuit jusqu'à 50 000 utilisateurs actifs mensuels. (Les 50 000 prochains coûteront 0,0055, ce qui signifie que si vous avez 100 000 MAU, ce sera 50000 * 0,0055 = 275 USD https://aws.Amazon.com/cognito/pricing/ )

Une autre chose, la documentation AWS .NET est un cauchemar à lire/rechercher à mon avis.

1
5argon