Firebase身份验证与AWS Cognito

Tom*_*mas 37 google-analytics amazon-web-services firebase amazon-cognito firebase-authentication

我们正在使用API​​ Gateway和Lambda在AWS上构建移动和Web应用程序,目前正在评估我们是否应该使用所有AWS Mobile Servcies(Cognito,Analytics,Mobile Hub等),或者我们是否应该使用Firebase(这提供了一些优势)喜欢远程配置).

我认为使用像Google Analytics,远程配置,崩溃报告,通知这样的firebase的非功能部分应该可以使用AWS后端.部分我不确定是身份验证层.

AWS Cognito可以很好地集成到API Gateway和Lamdba中,例如,只有经过身份验证的用户才能执行某些API调用.

如果我们使用Firebase身份验证,可以达到相同的行为吗?这有什么好的或坏的经历?

pmo*_*oni 30

我们也是这样做的.我们从Cognito开始,但转移到Firebase,因为我们对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");
        });
};
Run Code Online (Sandbox Code Playgroud)

我们还没有投入生产,但是对验证器的测试显示它在Google,Facebook和密码验证方面表现正常,而且速度也非常快(60 - 200毫秒).我能看到的唯一缺点是,您将需要为验证者lambda函数付费,而Cognito集成验证器是免费的.

  • 几乎1yr之后更新: - 我离开了API Gateway自定义身份验证器,主要是因为我无法使用cloudformation脚本自动部署它.我的解决方案现在是在API缓存令牌中直接进行身份验证一段时间,就像Authenticator那样,以避免过多的验证. (2认同)
  • 你知道你不喜欢 Cognito 的事情是否仍然是真的吗? (2认同)

Azi*_*ved 20

TL; DR; Firebase> Cognito

我们首先开始使用Cognito,但我们最终意识到,当它使用联合身份(例如,Google登录,Facebook登录等)时,它有一种残酷的气味.对于Cognito用户池(即允许用户使用用户名和密码进行注册),您可以使用内置的API Gateway Cognito用户池授权程序,它可以很好地工作.您无需编写自己的自定义授权程序或任何内容.

但是,如果要支持联合身份,则需要将API网关上的身份验证更改为IAM身份验证,然后让每个客户端sigv4签署请求,这对我们来说是一个棘手的问题,并且需要花费大量的开发时间.选项2是让API Gateway为每个客户端的API调用生成代码......在我看来,这证明了与Cognito的繁琐集成.

我们让Firebase通过API Gateway的自定义授权程序工作.在所有客户端(iOS,Android和Web)上轻而易举.API网关端点链接到Lambda函数,Lambda函数能够代表调用端点的用户与DynamoDB,S3和其他Web服务进行通信.lambda函数知道调用用户是谁,因为自定义授权者在JWT中返回了电子邮件地址.

这是一个非常基本的Firebase自定义授权程序,它将JWT中的用户电子邮件作为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: '*'
                }
            ]
        }
    };
}
Run Code Online (Sandbox Code Playgroud)

然后$context.authorizer.principalId,您可以在API网关映射模板中使用以检索电子邮件并将其传递给lambda X.

  • 我确实获得了使用 Firebase+API Gateway 的联合身份。老实说,我不需要在后端做任何特定/定制的事情。对于客户端,只需确保在连接联合身份后从 Firebase 获取 JWT。如果您有兴趣了解我如何使用 Swift 在 iOS 客户端中做到这一点,请告诉我,我会发布一个要点。 (3认同)

Nic*_*zzi 5

Aws文档很混乱.Firebase中更好地记录了不同身份验证步骤的回调系统.结果是更清晰的代码和更好的对身份验证流程的控制.此外,Firebase用户界面更加用户友好.如果您打算使用内容提供程序和同步适配器,我建议您使用Firebase,因为您将拥有本地和远程(Firebase)数据库之间的数据同步的简单方法


sn.*_*rag 5

与 firebase 相比,aws cognito 提供了更多的用户身份验证方法。特别是,如果您正在开发一款游戏,它提供了通过 google 和 ios 游戏中心登录的便利。它提供同步排行榜和游戏中心提供的成就。Cognito 中有自动状态同步功能。但可以肯定的是,这非常令人困惑。实施需要太多时间。另一方面,firebase 身份验证的实施速度非常快。


Zen*_*eni 5

对我来说,如果您决定转移到其他一些身份验证服务提供商,交易破坏者能够导出具有所有详细信息的用户。

虽然这在 Firebase 中是可能的,但它在 AWS Cognitio 中不可用!你可以进入一年中的任何时间,但你永远不能离开:)。 https://forums.aws.amazon.com/thread.jspa?threadID=296932

  • 看起来至少现在存在。https://docs.aws.amazon.com/solutions/latest/cognito-user-profiles-export-reference-architecture/welcome.html (2认同)