Как создать веб-форму, позволяющую аутентифицированным пользователям загружать файлы на S3? - PullRequest
0 голосов
/ 18 января 2019

Как создать веб-приложение, которое принимает пользовательские данные и сохраняет файлы изображений, загруженные авторизованными пользователями в AWS? Пользователи, которые имеют право загружать файлы, являются пользователями Интернета, а не пользователями AWS IAM. В идеале, они получают доступ к этой сети из URL с параметром запроса, представляющим этого авторизованного пользователя. Я думаю о создании статического веб-сайта в S3, сохранении пользовательских входных данных и файлов изображений в подпапке S3 Bucket. Каждый авторизованный пользователь имеет право на чтение \ запись только в своей собственной подпапке. Однако, поскольку S3 без сервера, мне нужны подробности о том, как использовать лямбда и API Gateway или другие сервисы AWS для обработки запроса из веб-формы и загрузки файлов на S3. Кажется, что я могу использовать плагин Drupal или WordPress Webform для создания веб-формы и загрузки файлов на S3. В этом случае мне нужен экземпляр EC2 для Drupal \ WordPress вместо статического сайта S3. Я ищу предложения по лучшей архитектуре для этого проекта. Любые учебники, инструкции и примеры кодов приветствуются. Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 18 января 2019

Идея состоит в том, чтобы использовать 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, и он довольно близок к тому, чего вы хотите достичь.

Используя эту технику, сервер не требуется.

0 голосов
/ 18 января 2019

Если вы требуете, чтобы ваши пользователи проходили аутентификацию на вашем приложении, вам необходимо сохранить их учетные данные в некоторой базе данных (например, DynamoDB). Для этого вам понадобится какая-то внутренняя служба, которая будет выполнять процесс аутентификации - хранить учетные данные пользователей в БД, извлекать учетные данные пользователей из БД, проверять учетные данные.

Вы можете либо написать свой собственный сервер, либо перейти на безсерверный лямбда-подход с API Gateway. Но здесь важно то, что вам нужна эта внутренняя логика. Нет никакого способа достичь этого, используя только статический веб-хостинг S3 (но это может быть частью всей системы).

AWS IAM используется в этом сценарии только для создания роли, которая позволяет службе - EC2 / Lambda - выполнять операции чтения / записи в сегменте S3 и DynamoDB. Пользователи вашего приложения не имеют ничего общего с IAM.

Поток заявки будет:

  1. пользователь подписывается на ваше приложение
  2. ваше приложение создает в БД запись с учетными данными пользователя и указателем на некоторый ресурс S3, который будет уникальным для этого пользователя
  3. при входе пользователь пытается загрузить изображение, данные отправляются в ваше приложение
  4. ваше приложение извлекает запись запрашивающей стороны из БД, ищет указатель S3 и загружает туда изображение

С архитектурной точки зрения при проектировании такой системы необходимо учитывать множество факторов - объем трафика, требования к CI-CD и т. Д.

Если вы хотите что-то довольно простое, то вы можете создать свой REST API с помощью API Gateway, где каждому ресурсу-методу будет назначена соответствующая лямбда-функция (эти функции будут выполнять вышеупомянутую логику). Вы можете использовать пользовательские процессы аутентификации или использовать AWS Congnito. Наконец, вы можете разместить свою веб-страницу (при условии, что она статична в этой настройке) на S3, совершая вызовы ajax против вашего шлюза API.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...