web-dev-qa-db-ja.com

Firebase認証とAWS Cognito

API GatewayとLambdaを使用してAWSでモバイルアプリとウェブアプリを構築しており、現在、すべてのAWSモバイルサービス(Cognito、Analytics、Mobile Hubなど)を使用するか、代わりにFirebaseを使用するか(いくつかの利点があります)を評価していますリモート設定など)。

AWSバックエンドでは、Analytics、Remote Config、Crash Reports、Notificationなど、Firebaseの非機能部分を使用しても問題ないと思います。わからない部分は認証レイヤーです。

AWS Cognitoは、API GatewayとLamdbaにうまく統合されています。認証されたユーザーのみが特定のAPI呼び出しを実行できます。

代わりにFirebase Authenticationを使用する場合、同じ動作に到達できますか?これで良いまたは悪い経験はありますか?

35
Tomas

同じことをしています。 Cognitoから始めましたが、AWS Android SDKがGoogleとFacebookで認証フローを実装する方法に満足できなかったため、Firebaseに移行しました。コードは非常に古く、廃止されたメソッドを使用し、 Cognitoを使用しない場合は、AWS API Gatewayにカスタム認証システムを実装する必要があります。これは非常に簡単で、 https:/ /aws.Amazon.com/blogs/mobile/integrating-Amazon-cognito-user-pools-with-api-gateway/ 。トークン検証のFirebaseの手順は https://firebase.google。 com/docs/auth/admin/verify-id-tokens

以下は私のオーセンティケーターのコードの抜粋です。

'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");
        });
};

まだ実稼働していませんが、オーセンティケーターでのテストでは、Google、Facebook、およびパスワード認証で正しく動作し、非常に高速(60〜200ミリ秒)であることが示されています。私が見ることができる唯一の欠点は、Cognito統合オーセンティケーターが無料であるのに、オーセンティケーターのラムダ関数に対して課金されることです。

30
pmosconi

TL; DR; Firebase> Cognito

私たちは最初にCognitoから始めましたが、Federated Identities(Googleサインイン、Facebookログインなど)を使用すると、最終的には悪臭がすることに気付きました。 Cognitoユーザープール(つまり、ユーザーがユーザー名とパスワードでサインアップ/サインインできるようにする)の場合、組み込みのAPI Gateway Cognitoユーザープールオーソライザーを使用できます。独自のカスタム認証を作成する必要はありません。

ただし、フェデレーションIDをサポートする場合は、APIゲートウェイの認証をIAM Authに変更してから、すべてのクライアントsigv4がリクエストに署名する必要があります。オプション2は、API GatewayですべてのクライアントのAPI呼び出しのコードを生成することでした...これは、Cognitoとの面倒な統合の証です。

API Gatewayのカスタムオーソライザーを介してFirebaseを動作させました。すべてのクライアントで簡単でした(iOS、AndroidおよびWeb)。APIGatewayエンドポイントはLambda関数にリンクされ、DynamoDB、S3、およびその他のWebサービスに代わって通信できました。カスタム承認者がJWTで電子メールアドレスを返したため、ラムダ関数は呼び出し元のユーザーを知っていました。

以下は、JWTでユーザーの電子メールをprincipalIdとして返す、非常に基本的なFirebaseカスタムオーソライザーです。

'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: '*'
                }
            ]
        }
    };
}

その後、$context.authorizer.principalIdをAPI Gatewayマッピングテンプレートで使用して、電子メールを取得し、ラムダXに渡します。

19
Aziz Javed

AWSのドキュメントはかなり混乱しています。さまざまな認証手順のコールバックシステムについては、Firebaseで詳しく説明されています。その結果、コードがよりきれいになり、認証フローをより適切に制御できるようになります。さらに、Firebaseユーザーインターフェースはより使いやすくなっています。コンテンツプロバイダーと同期アダプターの使用を計画している場合は、Firebaseを使用することをお勧めします。ローカルとリモート(Firebase)データベース間でデータを同期する簡単な方法があるためです。

5
Nicola Gallazzi

aws cognitoは、firebaseよりも多くの方法でユーザーを認証します。特に、ゲームを構築している場合は、GoogleおよびiOSゲームセンターからログインする機能が提供されます。同期リーダーボードと、ゲームセンターが提供する成果を提供します。 Cognitoには自動状態同期機能があります。しかし、間違いなく、非常に混乱しています。実装に時間がかかりすぎます。一方、firebase認証の実装は非常に高速です。

2
sn.anurag

Unityを使用している場合のために、現在Unity SDKはCognitoユーザープールをサポートしていません。 (つまり、AWSがホストするユーザーのリスト)このため、現在thisしています。私の投稿を参照してください ここ 彼らはそれが真実であることを確認しました、現在(2017年6月26日)機能はまだ利用できず、Unityユーザーへの注意の欠如を示しているかもしれません。

ただし、ログインにFirebaseを使用する場合は、AWSサービスを使用するためにこれらの認証情報をさらに統合する必要があります。 (S3とDynamoDBを使用したいのですが、ログインしたユーザーのみが使用できます。)これにより、できるだけ早く時間とフラストレーションを節約するために、すべてをFirebaseに移動する必要があることに気付きました。 (リアルタイムDBはS3/DynamoDBよりも高価ですが、UnityにはAWS MobileAnalyticsに代わるものがあります)

AWS S3は最近、より良いUIになりました。これはGoogleのレベルに近いと思います。しかし、それ以外は、FirebaseのUIを使用する方がはるかに楽しいと思います。

また、Firebase認証は無料ですが、Cognitoは毎月最大5万人のアクティブユーザーまで無料です。 (次の50kのコストは0.0055です。つまり、10万MAUを持っている場合、50000 * 0.0055 = 275 USDになります https://aws.Amazon.com/cognito/pricing/

もう1つ、 AWS .NETドキュメント は、私の意見では読み/検索するのが悪夢です。

1
5argon