如何创建一个Web应用程序来接收用户输入并存储授权用户上传到AWS的图像文件?有权上传文件的用户是Web用户,而不是AWS IAM用户。理想情况下,他们从带有代表此授权用户的查询参数的URL访问该网站。我正在考虑在S3中创建一个静态网站,将用户输入和图像文件存储在S3存储桶子文件夹中。每个授权用户仅对其自己的子文件夹具有读/写权限。但是,由于S3是无服务器的,因此我需要有关如何使用lambda和API Gateway或其他AWS服务处理来自Web表单的请求并将文件上传到S3的详细信息。看来我可以使用Drupal或WordPress Webform插件来创建Webform并将文件上传到S3。在这种情况下,我需要Drupal \ WordPress的EC2实例,而不是S3静态网站。我正在寻找有关此项目的最佳体系结构的建议。欢迎使用任何教程,说明和示例代码。预先感谢。
答案 0 :(得分:1)
如果您要求用户对您的应用程序进行身份验证,则需要将其凭据存储在某个数据库(即DynamoDB)中。为此,您需要一些将执行身份验证过程的后端服务-将用户的凭据存储在数据库中,从数据库中检索用户的凭据,然后验证凭据。
您可以编写自己的服务器,也可以通过API Gateway使用无服务器Lambda方法。但是这里重要的是,您需要具有此后端逻辑。无法仅使用静态S3虚拟主机来实现它(但它可以成为整个系统的一部分)。
在这种情况下,仅使用AWS IAM创建角色,该角色允许服务EC2 / Lambda对S3存储桶和DynamoDB执行读/写操作。您的应用程序用户与IAM无关。
应用程序的流程为:
从体系结构的角度来看,在设计这样的系统时要考虑很多因素-流量,对CI-CD的要求等等。
如果您想简单一些,则可以使用API网关创建REST API,其中每个资源方法都将分配有适当的lambda函数(这些函数将执行上述逻辑)。您可以使用自定义身份验证流程,也可以利用AWS Congnito。最后,您可以在S3上托管网页(假设在此设置中它是静态的),并针对API网关进行Ajax调用。
答案 1 :(得分:1)
想法是使用AWS Cognito。 Cognito Federated Identities允许向经过身份验证的用户出售临时访问令牌。它与Login With Amazon,Facebook,Google或任何使用OpenID或SAML的语言集成。
您的单页Web应用可以通过AWS SDK for Javascript访问Cognito。
因此,其想法是在您的网页上提出身份验证。我正在使用Login with Amazon或类似名称。您还可以选择使用Cognito用户池(Cognito在其中存储用户个人资料并提供登录,注册,密码恢复等功能)
通过身份验证后,您的Javascript代码可以调用refresh()
上的AWS.Config.credentials
,并传递从上述身份验证步骤收到的访问令牌。 refresh()
会依次调用Cognito的API来接收临时的和特定于用户的访问令牌。
function initializeCognito(access_token) {
return new Promise((resolve, reject) => {
// Initialize the Amazon Cognito credentials provider
AWS.config.region = 'us-east-1'; // Region
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'us-east-1:cognito pool id', // < -- insert your cognito pool ID here
Logins: {
'www.amazon.com': access_token
}
});
console.log("Calling Cognito to refresh AWS Credentials");
// get AWS credentials
AWS.config.credentials.refresh(function (err) {
if (err) {
console.log("Error when calling Cognito");
console.log(err, err.stack);
reject(err);
} else {
console.log("Cognito credenials received ");
resolve(AWS.config.credentials);
}
});
});
}
完成此操作后,其余代码可以调用任何AWS开发工具包API来调用后端服务,包括S3,DynamoDB ...
以下是DynamoDB的示例:
function insertIntoDDB(profile, text) {
return new Promise((resolve, reject) => {
var dynamodb = new AWS.DynamoDB();
var params = {
Item: {
"cognitoid": { //hash key
S: profile.cognito_id
},
"userid": {
S: profile.user_id
},
"text": {
S: text
},
"creationtime": { // sort key
N: Math.round(new Date() / 1000).toString()
},
"expirationtime": { // 1 month later ?
N: (Math.round(new Date() / 1000) + (1 * 60 * 60 * 24 * 30)).toString()
}
},
TableName: "my_table"
};
dynamodb.putItem(params, (err, data) => {
if (err) {
console.log("Error when calling DynamoDB");
console.log(err, err.stack); // an error occurred
reject(err);
} else {
// console.log(data); // successful response
resolve(data);
}
});
});
}
AWS开发工具包为您管理身份验证,如您所见,不包含传递访问密钥,秘密密钥的代码。访问密钥和秘密密钥由Cognito为该特定用户生成,并存储在AWS.config.credential
对象中。访问密钥和秘密密钥的范围受到限制,时间也受到限制。
要限制范围,请在Cognito控制台上定义IAM角色以与经过身份验证的用户相关联,向他们授予仅访问代码所需的服务和操作的权限。另外,S3和DynamoDB允许使用fine grained permission,从而允许您限制对存储桶或表中行中特定键(文件夹)的写访问。
您可以在https://alexademo.ninja/skills/myteacher/index.html看到此技术的实际效果,我将其写为与“ My Pronunciation Teacher” Alexa Skill一起使用。
还有一个完整的教程,将向您展示如何使用适用于JavaScript的AWS开发工具包将图片从Web表单上载到AWS Documentation中的S3。这段代码还利用了Cognito,非常接近您想要实现的目标。
使用此技术,不需要后端服务器。