Постоянная ошибка типа при попытке получить getObject в корзине S3, требующей аутентифицированного доступа - PullRequest
0 голосов
/ 01 января 2019

Используя AWS JavaScript SDK, я пытаюсь прочитать определенную корзину S3, когда аутентифицированный пользователь Cognito вошел в защищенную область моего веб-сайта.Я подтвердил, что я вхожу как аутентифицированный пользователь, благодаря действительному authToken, который я получаю после подтверждения моей Cognito Identity.Фактически, я протестировал и доказал весь процесс регистрации, многофакторной проверки, входа и выхода из Cognito.

По какой-то причине, когда я выполняю свой первый запрос s3.getObject, я получаю следующееTypeError, хотя я УВЕРЕН, я передаю строку (ключ) в качестве первого аргумента.Вот ошибка:

TypeError: First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.

Теперь, во-первых, я включаю JavaScript SDK через тег script на HTML-странице следующим образом:

script src="https://sdk.amazonaws.com/js/aws-sdk-2.154.0.min.js"></script>

У меня есть следующая роль IAMсозданный Cognito:

Cognito_MyAppNameAuth_Role

К которому я добавил следующую политику S3:

{
  "Sid": "VisualEditor1",
  "Effect": "Allow",
  "Action": "s3:ListBucket",
  "Resource": "arn:aws:s3:::my-bucket-name"
},
{
  "Sid": "VisualEditor2",
  "Effect": "Allow",
  "Action": "s3:GetObject",
  "Resource": "arn:aws:s3:::my-bucket-name/*"
}

Примечание. Визуальный редактор автоматически вставил эти Sids после того, как я их отредактировал.

Теперь код, который я выполняю для чтения моего сегмента S3, находится в файле .js, который я включаю через тег.Он запускается после загрузки ...

<body onLoad="bodyOnLoad();">

Первое, что делает код, это проверяет учетные данные пользователя.Я получаю пул пользователей;тогда я получаю текущего пользователя.Тогда я получаю сессию.И затем я вызываю учетные данные пользователя с помощью AWS.CognitoIdentityCredentials () следующим образом:

AWS.config.update({ //testing... 12/29
  region: 'us-east-1',
  accessKeyId: 'anything',
  secretAccessKey: 'anything',
  credentials: new AWS.CognitoIdentityCredentials({
     IdentityPoolId: 'us-east-1:numbers-and-letters-and-bears-oh-my',
     Logins: {
        'cognito-idp.us-east-1.amazonaws.com/us-east-1-xxxyyyxxx': session.getIdToken().getJwtToken()
        }
     })
});

Я буквально указываю «что-нибудь» для accessKeyId и secretAccessKey, поскольку я не считаю, что они требуются.Когда это работает, нет ошибок.Все появляется в порядке с проверкой моего аутентифицированного пользователя, принадлежащего требуемому Cognito Identity Pool.

Вот попытка s3.getObject, которая происходит далее и приводит к приведенной выше ошибке TypeError:

const s3 = new AWS.S3({
  apiVersion: '2006-03-01',
  params: {
    Bucket: 'my-bucket-name'
  }
});

var params = {
  Bucket: 'my-bucket-name',
  Key: 'index.json'
};

s3.getObject(params, (err, data) => {
  if (err) {
    // EXECUTION LANDS HERE!
    callback(err);
    return;
  }

  const content = data.Body.toString('utf-8');
  callback(null, content);
});
}

Я пробовал много перестановок на пути передачи параметров в метод getObject.В том числе ..

s3.getObject({Key: 'index.json'}, (err, data) => { ... }

Я получаю одну и ту же ошибку каждый раз.Что в мире я делаю неправильно ???Заранее спасибо !!!

ОБНОВЛЕНИЕ 01.01.2009 - HNY!

Отвечая Джону ниже, я изменил свой код, чтобы переместить все в ту же область,(Еще раз спасибо.) Хороший совет, но я все еще получаю ту же ошибку TypeError (показано выше).Теперь, я думаю, Джон может быть прав, что настоящая проблема связана с моей аутентификацией или политикой Identity Pool.Если я удаляю фиктивные accessKeyId и secretAccessKey из AWS.config.update (как Джон удалил их в своем примере), я получаю другую ошибку: я получаю ошибку 400, а затем это ..

Error: Invalid login token. Issuer doesn't match providerName

Вот код, который у меня есть в config.js:

window._config = {
    cognito: {
        userPoolId: 'user-pool-id',
        userPoolClientId: 'user-pool-client-id',
        region: 'us-east-1'
    },
    api: {
        invokeUrl: 'https://<invoke-url>.execute-api.us-east-1.amazonaws.com/prod'
    }
};

Вот новый поток кода после объединения всех в одну и ту же область:

function loadFileFromS3(key, callback) {
  console.log('loadFileFromS3: ' + key); //key is 'index.json'

  var poolData = {
      UserPoolId: _config.cognito.userPoolId,
      ClientId: _config.cognito.userPoolClientId
  };

  var userPool;

  userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);

  if (typeof AWSCognito !== 'undefined') {
      AWSCognito.config.region = _config.cognito.region;
  }

  var cognitoUser = userPool.getCurrentUser();

  if (cognitoUser) {
      cognitoUser.getSession(function sessionCallback(err, session) {
          if (err) {
              reject(err);
          } else if (!session.isValid()) {
              resolve(null);
          } else {
              console.log('authToken is ' + session.getIdToken().getJwtToken());
              // Configure the credentials provider to use your identity pool
              AWS.config.update({ //testing... 12/29
                region: 'us-east-1',
                accessKeyId: 'anything', //remove gives me 400 error as shown above
                secretAccessKey: 'anything', // 
                credentials: new AWS.CognitoIdentityCredentials({
                  IdentityPoolId: 'us-east-1:<identity-pool-id>',
                  Logins: {
                    'cognito-idp.us-east-1.amazonaws.com/us-east-1-<user-pool-id>': session.getIdToken().getJwtToken()
                  }
                })
              });
              console.log('AWS.config update happened...');

              // call refresh to authenticate user and get credentials
              AWS.config.credentials.refresh((error) => {
                if (error) {
                  console.error(error);
                } else {
                  console.log('Success');
                  // NOTE: The credential are valid HERE
                  const s3 = new AWS.S3({
                    apiVersion: '2006-03-01',
                    params: {
                      Bucket: 'my-bucket-name'
                    }
                  });
                  var params = {
                    Bucket: 'my-bucket-name',
                    Key: key
                  };

                  console.log('s3.getObject with key: ' + key);
                  s3.getObject(params, (err, data) => {
                    if (err) {
                      console.log('getObject ERROR: ' + err);
                      callback(err);
                      return;
                    }

                    const content = data.Body.toString('utf-8');
                    callback(null, content);
                  });
                }
              });
          }
      });
  } else {
      resolve(null);
  }

}

ОБНОВЛЕНИЕ

Хорошо.Проблема не имела ничего общего с аргументом, который я передавал s3.getObject, и все, что было связано с опечаткой в ​​моем UserPoolId в Logins.Мне не хватало подчеркивания.Г!Спасибо, Джон, за то, что привел меня в порядок.Я бы навсегда запутался, если бы вы не предложили мне перепроверить.

Исправление кода выше:

Logins: {
   'cognito-idp.us-east-1.amazonaws.com/us-east-1_<user-pool-id>': session.getIdToken().getJwtToken() //underscore after us-east-1_ !!!

1 Ответ

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

Я думаю, что ваша настоящая проблема в том, что у вас нет учетных данных для пользователя.

AWS.config.update({ //testing... 12/29
  region: 'us-east-1',
  credentials: new AWS.CognitoIdentityCredentials({
    IdentityPoolId: 'us-east-1:numbers-and-letters-and-bears-oh-my',
    Logins: {
      'cognito-idp.us-east-1.amazonaws.com/us-east-1-xxxyyyxxx': session.getIdToken().getJwtToken()
    }
  })
});

// call refresh to authenticate user and get credentials
AWS.config.credentials.refresh((error) => {
  if (error) {
    console.error(error);
  } else {
    console.log('Success');
    // NOTE: The credential are valid HERE
    // Put your S3 code HERE.
    const s3 = new AWS.S3({
      apiVersion: '2006-03-01',
      params: {
        Bucket: 'my-bucket-name'
      }
    });
    // Continue with the rest of your S3 code HERE
  }
});
// The credentials are not valid HERE
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...