3

我正在尝试使用联合身份验证制作无服务器应用程序(ReactJS、API Gateway、AWS Lambda、DynamoDB)。以下是我所设想的那种架构(为简洁起见,没有添加 STS。我也不认为我完全理解流程):

认证顺序

我创建了触发 lambda 函数的 API Gateway 端点。我想先用 google 对我的用户进行身份验证,如果他们成功了,那么他们应该能够使用 API 端点。

第一步是使用标准 Outh2 向 google 验证用户。为此,我创建了 2 个未经身份验证的端点 /signin/google 和 /callback/google。一旦我在回调 lambda 函数中从谷歌获得成功的身份验证响应,我就有了可以使用的 id_token (以及其他)。

目前,我有 2 种方法可用于验证 API。

  1. 构建可用于 API 端点的自定义授权方。这是代码(https://github.com/prabhatsharma/api-gateway-custom-authorizer/)。这很简单。我可以使用 google 提供的相同 id_token 来验证 API 端点。自定义授权方将验证 id_token 是否良好并授予对端点的访问权限。它还将缓存结果,以便每次都不需要此验证。(这是以这种方式重用google id_token 的好方法吗?)您可以使用授权方(https://github.com/prabhatsharma/lambda-custom-auth

  2. 我可以使用 AWS cognito 进行身份验证。为此,我创建了一个联合身份池,并将谷歌应用程序客户端 ID 设置为 cognito 控制台。在我的/callback/google lambda 函数中,我使用AWS SDK 来获取identityId、sessionToken 和accessKeyId。(源代码https://github.com/prabhatsharma/lambda-cognito-auth

    // Add the Google access token to the Cognito credentials login map.
    AWS.config.credentials = new AWS.CognitoIdentityCredentials({
        IdentityPoolId: config.COGNITO_IDENTITY_POOL_ID,   //dauth
        Logins: {
            'accounts.google.com': JSON.parse(body).id_token
        }
    });
    

现在我可以使用凭据使用以下代码获取令牌

    // Obtain AWS credentials
    AWS.config.credentials.get(function () {
        // Access AWS resources here.
        // Credentials will be available when this function is called.
        var identityId = AWS.config.credentials.identityId;

        var cognitoidentity = new AWS.CognitoIdentity();

        var params = {
            IdentityId: identityId, /* required */
            Logins: {
                'accounts.google.com': JSON.parse(body).id_token
            }
        };

        cognitoidentity.getOpenIdToken(params, function (err, data) {
            if (err) console.log(err, err.stack); // an error occurred
            else {
                console.log(data);           // successful response
                res.headers = {
                    location: config.APPLICAION_URL + '/auth/google?' + querystring.stringify(data)
                }
                callback(null, res);   //redirect to front end application
            }
        });

我现在可以将 identityId 和 Token 传递给我的前端 reactJS 应用程序。

这是我需要一点帮助来理解这个概念的地方。我现在可以在浏览器中使用 AWS 开发工具包来访问 AWS 资源。但是坚持!!!通过 Gateway 创建标准 RESTful API 的目的不就是使用标准 javascript 而不依赖任何特定库吗?直接使用 AWS SDK 看起来更适合 android/ios/unity 应用程序的用例。我希望我团队中的开发人员也能够使用他们在这种情况下使用的标准前端 javascript 库。此外,我不想将导出的 API SDK 用于我的 API 端点,并且真的希望保持前端应用程序不受 AWS SDK 细节的影响。手动使用 v4 签名对每个请求进行签名是多余的工作。我们不能使用 Cognito 进行基于标准令牌的 API 端点访问吗?

这种身份验证的最佳实践是什么?我在想正确的方向吗?

免责声明 - 请不要使用 repos 中的代码。它正在进行中,尚未准备好生产。

4

1 回答 1

0

您可以将自定义授权器功能与 oauth2 令牌一起使用。或者,您可以使用 Cognito 和相应的 IAM 角色来管理用户对您的 AWS 资源的访问。

您在流程图中描述的第二种方法不需要在每个请求前使用 auth lambda,并允许您控制从前端(如 IoT ie)对其他 AWS 资源的访问。

一旦你获得了 secretKey、accessKey、sessionToken 和 region,你只需要对 APIG 的每个请求进行签名。您不需要 AWS 开发工具包即可执行此操作。

如果您不想使用导出的 API,则必须自己签署请求。它是在 中实现的,sigV4Client.js因此很容易复制。无论如何,您将需要很少的依赖项,那么为什么不使用导出的 API?你已经在使用这么大的 React。

于 2016-10-30T14:30:09.280 回答