我正在将 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
如有任何帮助,我们将不胜感激。
这实际上是一个三步过程:
定义一个新的身份池,并将其与来自 Amplify 的经过身份验证的用户池中的登录用户关联。说明位于 https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-integrating-user-pools-with-identity-pools.html
为 S3 存储桶设置 CORS。直接从 Lambda 函数使用 SDK 时不需要这样做,但对于 Amplify 则需要这样做。说明位于 https://docs.aws.amazon.com/AmazonS3/latest/userguide/ManageCorsUsing.html
配置与身份池关联的策略以授予对 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);
}
});
我希望在没有身份池的情况下执行此操作,因此我不会将其标记为接下来几天的最终答案,以防万一有其他选择。
使用 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 表。
尽管文档由于某种原因没有谈论它,
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
来传递凭据。