我有一个移动应用程序,它让用户通过 AWS Cognito 进行身份验证,他们最终进入用户池。他们可以毫无问题地将对象放入存储桶中,但无法删除。我想做的是让每个登录用户能够删除存储桶中的文件。
文件的路径例如:my_bucket_name/protected/eu-west-2:de55c2rf-8f1e-836d-88f9-82da662aau6dt/videos/video1
要删除,我称之为:
import { Storage } from 'aws-amplify';
. . .
delFromS3 = async () => {
Storage.remove('protected/eu-west-2:de55c2rf-8f1e-836d-88f9-82da662aau6dt/videos/video1')
.then(result => console.log('Deleted Video from S3'))
.catch(err => console.log('Deleting video from S3 error: ', err));
}
调用此函数时,我不断收到错误"访问被拒绝",因此我添加了一个存储桶策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "cognito-identity.amazonaws.com"
},
"Action": "s3:DeleteObject",
"Resource": "arn:aws:s3:::my_bucket_name/*"
}
]
}
这个函数返回结果的唯一时间是当我放"Principal": "*"
但这使我的存储桶对任何人公开时,我不想这样做。它也不接受此作为有效的Prinipal策略:
"Principal": { "AWS": [ "arn:aws:cognito-idp:eu-west-2:968257789397:userpool/eu-west-2_2ecGAT74q" ] }.
所以我需要知道正确的校长是什么。
因此,我要么需要一种方法来允许 cognito 用户池中的用户有权删除对象。或者因为我手动知道每个用户子存储桶中文件的路径(例如/protected/eu-west-2:de55c2rf-8f1e-836d-88f9-82da662aau6dt/videos/video1
(只需在我的delFromS3()
函数中传递它。我的存储桶策略应该读取什么?我还缺少什么吗?
请帮忙!
我会为删除等操作创建一个 IAM 用户,并使用您的认知 ID 进行访问。对于 IAM 用户,您的委托人如下所示:
"Principal": {
"AWS": "arn:aws:iam::841367581918:user/your-iam-name"
},
您将在 api 文件的顶部为此用户提供访问密钥,如下所示:
const AWS = require('aws-sdk');
const s3 = new AWS.S3();
s3.config.update({
region: process.env.BUCKET_REGION,
accessKeyId: process.env.IAM_ACCESS_KEY,
secretAccessKey: process.env.IAM_SECRET_KEY
});
然后,要删除对象,请执行以下操作:
deleteObject: async (req, res) => {
const bucket = process.env.YOUR_BUCKET;
try {
// delete record in DB
//....
let cognitoId = req.user.cognitoId;
let key = cognitoId + '/' + path; // my folder name is user's cognitoId and path is the rest of url.
const params = {
Bucket: bucket,
Key: key
}
try {
await s3.headObject(params).promise();
console.log("File found");
try {
await s3.deleteObject(params).promise();
console.log("deleted successfully");
}
catch (error) {
console.log(error);
res.status(500).send(error.message);
}
}
catch (error) {
console.log(error);
res.status(500).send(error.message);
}
res.status(200).send("success");
}
catch (error) {
console.log(error);
res.status(500).send(error.message);
}
}
Amplify CLI 将帮助您针对"公有"、"受保护"和"私有"文件夹预置正确的 S3 存储桶策略。 https://aws-amplify.github.io/docs/ios/storage#restrict-access 要完成您想做的事情,您可以
使用Amplify.Storage 上传,使用
accessLevel: .protected
上传对象,将对象上传到 S3 下的<bucket>/protected/<key>
使用相同的访问级别下载以检索
<bucket>/protected/<key>
let options = StorageDownloadDataRequest.Options(accessLevel: .protected)
Amplify.Storage.downloadData(key: "myKey", options: options) { (event) in
...
}
本质上,放大存储插件在密钥前面预置存储访问级别。当调用中未指定访问级别时,默认情况下它将在"public"前面加上。
您可以在此处找到相关的博客文章:https://aws.amazon.com/blogs/mobile/introducing-aws-amplify-for-ios-and-android/
对应的示例应用:https://github.com/nikhil-dabhade/amplify-ios-samples/tree/master/samples/ios/amplify/storage/AmplifyStorageSampleApp