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



我正在为一个ReactJS应用程序使用AWS Amplify。我从Amplify中使用的唯一两个功能区域是身份验证和托管。这两个都工作得很好,与项目关联的Cognito用户池也按预期工作,在成功认证后向React组件提供登录用户。

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

我试图从@aws-sdk/credentials-providers使用fromWebToken,但我没有身份池;我正在使用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

任何帮助都是感激的。

这是一个三步的过程:

  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);
}
});

我希望在没有身份池的情况下这样做,所以我不会在接下来的几天中将其标记为最终答案,以防有其他选择。

使用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表。

最新更新