这个想法是使用AWS Cognito。 Cognito Federated Identities 允许向经过身份验证的用户提供临时访问令牌。它与 Login With Amazon、Facebook、Google 或任何使用 OpenID 或 SAML 的平台集成。
您的单页 Web 应用可以通过 AWS SDK for Javascript 访问 Cognito。
所以我们的想法是在您的网页上提出身份验证。我正在使用Login with Amazon 或类似的。您还可以选择使用 Cognito 用户池(Cognito 存储用户配置文件并提供登录、注册、密码恢复等功能)
一旦通过身份验证,您的 Javascript 代码就可以在 AWS.Config.credentials 上调用 refresh(),并传递从上述身份验证步骤收到的访问令牌。 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 SDK 为您管理身份验证,如您所见,传递访问密钥(秘密密钥)不涉及任何代码。访问密钥和秘密密钥由 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,它非常接近您想要实现的目标。
使用这种技术,不需要后端服务器。