我们正在使用API Gateway和Lambda在AWS上构建移动和Web应用程序,目前正在评估我们是否应该使用所有AWS Mobile Servcies(Cognito,Analytics,Mobile Hub等),或者我们是否应该使用Firebase(提供远程配置等优点。
我认为使用分析,远程配置,崩溃报告,通知等firebase的非功能部分应该可以使用AWS后端。部分我不确定是身份验证层。
AWS Cognito很好地集成到API Gateway和Lamdba中,例如只有经过身份验证的用户才能执行某些API调用
如果我们使用Firebase身份验证,是否可以达到相同的行为? 对此有任何好的或坏的经历?
答案 0 :(得分:27)
以下是我的身份验证员代码的摘录:
'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毫秒)。 我可以看到的唯一缺点是,您需要为authenticator lambda函数付费,而Cognito集成验证器是免费的。
答案 1 :(得分:18)
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: '*'
}
]
}
};
}
然后,您可以在API网关映射模板中使用$context.authorizer.principalId
来检索电子邮件并将其传递给lambda X.
答案 2 :(得分:5)
Aws文档很混乱。 Firebase中更好地记录了不同身份验证步骤的回调系统。结果是更清晰的代码和更好的对身份验证流程的控制。此外,Firebase用户界面更加用户友好。如果您打算使用内容提供程序和同步适配器,我建议使用Firebase,因为您将拥有本地和远程(Firebase)数据库之间的数据同步的简单方法
答案 3 :(得分:2)
答案 4 :(得分:1)
如果您使用Unity,目前Unity SDK不支持Cognito用户池。 (也就是说,AWS主持的用户列表)我因此而犹豫不决。请参阅我的帖子here他们确认这是真的,目前(26/06/2017)该功能仍然无法使用,这可能表明他们对Unity用户缺乏关注。
但是,如果我使用Firebase进行登录,我需要对这些凭据进行更多集成才能使用AWS服务。 (我想使用S3和DynamoDB,但只有登录用户才能使用它。)这也让我意识到我应该把所有内容都移到Firebase,以尽快节省我的时间和挫折。 (实时数据库比S3 / DynamoDB更昂贵,但Unity有自己的AWS MobileAnalytics替代品)
AWS S3最近获得了更好的用户界面,我认为这与谷歌的水平相近。但除此之外,我认为Firebase的UI使用起来更加快乐。
此外,Firebase身份验证是免费的,而Cognito每月最多可获得5万活跃用户。 (下一个50k将花费0.0055,这意味着如果你有100k MAU,它将是50000 * 0.0055 = 275美元https://aws.amazon.com/cognito/pricing/)
还有一件事,AWS .NET documentation是我认为阅读/搜索的噩梦。
答案 5 :(得分:0)
对我而言,如果您决定转至其他身份验证服务提供商,则交易突破者可以导出所有详细信息的用户。
虽然在Firebase中可以实现,但在AWS Cognitio中不可用! 您可以输入一年中的任何时间,但永远不能离开:)。 https://forums.aws.amazon.com/thread.jspa?threadID=296932