Идея состоит в том, чтобы использовать AWS Cognito . Cognito Federated Identities позволяет предоставлять временные токены доступа аутентифицированным пользователям. Он интегрируется с входом в систему через Amazon, Facebook, Google или любым другим устройством, поддерживающим OpenID или SAML.
Ваше веб-приложение Singe Page может получить доступ к Cognito через AWS SDK для Javascript .
Так что идея состоит в том, чтобы предложить аутентификацию на вашей веб-странице. Я использую Войти через Amazon или аналогичный. Вы также можете выбрать использование Cognito User Pool (где Cognito хранит профили пользователей и обеспечивает вход, регистрацию, восстановление пароля и т. Д.)
После аутентификации ваш код Javascript может вызывать refresh()
на AWS.Config.credentials
, передавая маркер доступа, полученный на шаге аутентификации, описанном выше. refresh()
, в свою очередь, вызовет API Cognito для получения временного и пользовательского токена доступа.
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);
}
});
});
}
Как только это будет сделано, остальная часть вашего кода сможет вызывать любой API AWS SDK для вызова внутренних служб, в том числе 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 допускают мелкозернистое разрешение , что позволяет вам ограничивать доступ на запись к определенным ключам (папкам) в вашей корзине или строке в таблице.
Вы можете увидеть эту технику в действии на https://alexademo.ninja/skills/myteacher/index.html Я написал это для работы с " учителем произношения " Алекса Скиллом.
Существует также полное руководство, которое покажет вам, как использовать AWS SDK для JavaScript для загрузки изображений из веб-формы в S3 в Документации AWS . Этот код также использует Cognito, и он довольно близок к тому, чего вы хотите достичь.
Используя эту технику, сервер не требуется.