通过 Amplify Auth 获取登录用户的凭据

问题描述 投票:0回答:3

我正在将 AWS Amplify 用于 ReactJS 应用程序。我使用 Amplify 的唯一两个功能区域是身份验证和托管。这两个工作正常,并且与该项目关联的 Cognito 用户池正在按预期工作,在成功身份验证后将登录的用户提供给 React 组件。

我的下一步是查询 Amplify 配置之外的其他 AWS 资源,从 S3 存储桶和 DynamoDB 表开始。我正在尝试使用 AWS 客户端 SDK 来实现这些目的,但无法弄清楚如何使用当前登录用户的凭证。

我尝试使用

fromWebToken
中的
@aws-sdk/credentials-providers
,但我没有身份池;我正在使用 Cognito 用户池,因为只有经过身份验证的用户才能访问该 Web 应用程序。所以我对如何继续感到困惑。我的想法是当前的用户凭据将自动用于任何客户端请求,但显然情况并非如此。

这是我的代码;请注意,这只是尝试展示我所尝试的内容,我的问题非常简单:如何获取当前经过身份验证的用户的凭证以与 S3 和其他 AWS 客户端 SDK 组件一起使用?

    // user is the currently logged in user. I can see the accessToken etc. here.
    console.log(user.signInUserSession.accessToken);

    const client = new S3Client({
        region: "us-west-2", credentials: fromWebToken({

            clientConfig: {region: "us-west-2"},
            roleArn: "arn:aws:iam::...",  // Got these from IAM for authenticated users
            webIdentityToken: user.signInUserSession.accessToken.jwtToken
        })
    });

我尝试使用客户端下载文件,但出现以下错误:

const command = new GetObjectCommand({
            Bucket: bucket,
            Key: key,
        });
const response = await client.send(command);

// Throws the error: No Cognito Identity pool provided for unauthenticated access

如有任何帮助,我们将不胜感激。

amazon-web-services amazon-cognito aws-amplify aws-sdk-js aws-amplify-sdk-js
3个回答
2
投票

这实际上是一个三步过程:

  1. 定义一个新的身份池,并将其与来自 Amplify 的经过身份验证的用户池中的登录用户关联。说明位于 https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-integrating-user-pools-with-identity-pools.html

  2. 为 S3 存储桶设置 CORS。直接从 Lambda 函数使用 SDK 时不需要这样做,但对于 Amplify 则需要这样做。说明位于 https://docs.aws.amazon.com/AmazonS3/latest/userguide/ManageCorsUsing.html

  3. 配置与身份池关联的策略以授予对 S3 存储桶的访问权限。这是常见的 IAM 策略内容。

我使用了以下库/导入:

import {S3Client, GetObjectCommand} from "@aws-sdk/client-s3";
import {fromCognitoIdentityPool} from "@aws-sdk/credential-providers";
import {Auth} from 'aws-amplify';

const Identity_pool_id = <identity pool ID>;

最后,通过以下代码,我能够正确获取文件:

    Auth.currentSession().then(data => {
        const client = new S3Client({
                region: "us-west-2",
                credentials: fromCognitoIdentityPool({
                    clientConfig: {region: "us-west-2"},
                    identityPoolId: Identity_pool_id,
                    logins: {
                        'cognito-idp.us-west-2.amazonaws.com/<user_pool_id>': data.getIdToken().getJwtToken()
                    }
                })
            }
        );
        try {
            const command = new GetObjectCommand({
                Bucket: bucket,
                Key: key,
                clientConfig: {region: "us-west-2"},
            });
            client.send(command).then(async (data) => {
                // const stats = JSON.parse(data.Body.toString());
                const data2 = await data.Body.transformToString();
                console.log(data2);
            });
        } catch (err) {
            console.log(err);
        }
    });

我希望在没有身份池的情况下执行此操作,因此我不会将其标记为接下来几天的最终答案,以防万一有其他选择。


0
投票

使用 Amplify Authentication,那么您可以检索当前会话并获取访问令牌等

import { Auth } from 'aws-amplify';

Auth.currentSession()
  .then(data => console.log(data))
  .catch(err => console.log(err));

对于 S3,您可以使用 Amplify 的存储 API。由于您的 S3 存储桶已存在,只需将其连接到 Amplify

amplify import storage

获取数据:

const result = await Storage.get(`filename.txt`, { download: true });

// data.Body is a Blob
result.Body.text().then(string => { 
  // handle the String data return String 
});

amplify import storage
命令还可用于连接现有 DynamoDB 表


0
投票

尽管文档由于某种原因没有谈论它,

credentials
是你从
AuthSession
获得的
fetchAuthSession()
的对象:

import { fetchAuthSession } from "aws-amplify/auth";

const authSession = await fetchAuthSession();
const credentials = authSession.credentials;

当您实例化

AWSCredentials
时,这些
AWSCredentialIdentity
可以用作
Client
。例如,对于具有
DynamoDB
SDKv3
客户。

import type { DynamoDBClientConfigType } from "@aws-sdk/client-dynamodb";
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";

const config: DynamoDBClientConfigType = {
  region: "<YOUR_REGION>",
  credentials: userCredentialsStore.credentials,
};
const ddbClient = new DynamoDBClient(config);

请注意,这仍然需要

identity pool
来传递凭据。

© www.soinside.com 2019 - 2024. All rights reserved.