如何在AWS上获取凭证?我必须使用AWS Cognito SDK还是AWS SDK?

4
我正在使用AWS SDK为AWS S3构建一个富客户端前端,将IAM凭证硬编码到AWS SDK配置中可以正常工作,但我想通过AWS Cognito为最终用户提供访问权限。
如何获取我在Cognito用户池中创建的用户的凭证?
AWS文档非常不清楚。我看到过使用AWS SDK的示例,也看到过需要使用不同的AWS Cognito SDK的示例。哪篇文档是正确的?
对于这个特定的项目,我不想使用任何第三方联合身份验证。
更新2: AWS Cognito SDK已经合并到一个名为AWS Amplify的新库中。 https://github.com/aws/aws-amplify 更新1: 问题有两个方面。理解术语并正确设置Cognito是第一部分。感谢Bruce0让我开始运行。第二部分是javascript部分。事实证明,你需要两个单独的库来纯粹从javascript进行Cognito用户身份验证。
这是我的解决方案。如果它看起来对你来说很陌生,请确保你已经学习了基于es6的promise/async/await。要在节点中运行它,只需要使用babel、preset es2015、preset stage-2和babel-transform-runtime插件进行预处理。如果您想在浏览器中运行它,您可能需要使用webpack的babel-loader(设置非常复杂,请预先警告)。
import AWS from 'aws-sdk/global';
import S3 from 'aws-sdk/clients/s3';
import {
  AuthenticationDetails,
  CognitoUser,
  CognitoUserPool,
} from 'amazon-cognito-identity-js';

const REGION = 'some-string-value';
const USER_POOL_ID = 'some-string-value';
const IDENTITY_POOL_ID = 'some-string-value';
const APP_CLIENT_ID = 'some-string-value';
const POOL_KEY = `cognito-idp.${REGION}.amazonaws.com/${USER_POOL_ID}`;

let Username = 'some-string-value';
let Password = 'some-string-value';

let authenticationDetails = new AuthenticationDetails({
  Username,
  Password
});

let userPool = new CognitoUserPool({
  UserPoolId: USER_POOL_ID,
  ClientId: APP_CLIENT_ID
});

let cognitoUser = new CognitoUser({
  Username,
  Pool: userPool
});

let skateboards = {
  mfaRequired(codeDeliveryDetails) {
    let mfaCode = prompt('MFA code is required!');

    cognitoUser.sendMFACode(mfaCode, mfaRequired);
  },
  newPasswordRequired(userAttributes, requiredAttributes) {
    delete userAttributes.email_verified; // it's returned but not valid to submit

    let newPassword = prompt('A new password is required!');

    cognitoUser.completeNewPasswordChallenge(newPassword, userAttributes, newPasswordRequired);
  }
};

let updateAWSCreds = (jwtToken) => {
  AWS.config.credentials = new AWS.CognitoIdentityCredentials({
    IdentityPoolId: IDENTITY_POOL_ID,
    Logins: {
      [POOL_KEY]: jwtToken
    }
  });
};

let authenticateCognitoUser = async ({mfaRequired, newPasswordRequired} = skateboards) => {
  return new Promise((resolve, reject) => {
    cognitoUser.authenticateUser(authenticationDetails, {
      onSuccess(result) {
        let jwtToken = result.getIdToken().getJwtToken();
        updateAWSCreds(jwtToken);
        resolve();
      },
      onFailure(err) {
        reject(err);
      },
      mfaRequired,
      newPasswordRequired
    });
  });
};

let doSomethingInS3ForExample = async () => {
  await authenticateCognitoUser();

  // now do your stuff
};

doSomethingInS3ForExample();

https://gist.github.com/sbussard/7344c6e1f56051da0758d1403a4343b1


我不会在客户端上过多地使用aws sdk,因为这需要在客户端上公开AWS秘密密钥。我要么选择cognito,要么在后端使用aws sdk并在客户端上使用预签名请求。 - Guig
1
在Cognito中获取凭证的唯一方法是创建联合身份池。cognitoIdentity和credentialsProvider方法是获取凭证的方式。您不必联合身份即可使用联合身份池,但是您需要拥有identityId(这些仅存在于池中)。因此,您将在联合身份池中只有一个cognitoUserPool作为身份验证提供程序(没有任何内容将被联合),并且IAM角色由该身份池提供(通常为已验证和未经验证),但您可以拥有更多角色。 - Bruce0
@Bruce0 确实如此!这就是我到目前为止的体验。Cognito看起来真的很革命性。非常感谢您的帮助,无疑将在未来几个月对数百万人产生积极影响,排除空格;) - Stephen
2个回答

5
唯一获得Cognito凭据的方法是创建联合身份池。cognitoIdentity和credentialsProvider方法是获取凭证的方法。
您不必联合身份,即可使用联合身份池,但是需要拥有identityId(这些仅存在于池中)才能获取凭据。
因此,您将在联合身份池中仅拥有cognitoUserPool作为身份验证提供者(没有任何联合),并且由该身份池提供IAM角色(通常为已验证和未经验证),但您也可以拥有更多的角色。
这里是一个链接到解释Cognito基本混乱方面的PowerPoint演示文稿,希望对您有所帮助。Cognito概述 最后,我建议您使用AWS Mobile Hub(至少作为示例)来开始实施,而不是使用IOS SDK。Mobile Hub是一个轻量级的包装器,但可以完成大量繁重的工作,并具有良好的架构。

看起来非常棒。移动中心似乎有一些不错的功能可以进行设置。但它没有任何针对浏览器/JavaScript的东西。你的回答对我非常有帮助,所以当我连接成功后,我可能会将其标记为正确答案,也许还会编辑添加浏览器特定部分。非常感谢你的帮助! - Stephen
你说得对,移动集线器不支持Javascript。但它可以帮助你正确设置IAM角色,并帮助你设置标识池和用户池,并为你想要访问的内容执行IAM策略,如果你不熟悉所有这些内容,它会变得有点复杂。祝你好运,谢谢。 - Bruce0

1
以下内容对我有效,我设置了cognito来创建身份池,并使用IAM将配置文件添加到用户中(我完全按照此链接操作:https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/s3-example-photo-album.html)。
import S3 from 'aws-sdk/clients/s3'
import AWS from 'aws-sdk/global'

AWS.config.update({
  region: process.env.AZ_REGION,
  credentials: new AWS.CognitoIdentityCredentials({
    IdentityPoolId: 'XXX'
  })
});

const s3 = new AWS.S3({
apiVersion: '2006-03-01',
params: {Bucket: process.env.AZ_BUCKETNAME},
      });

我只希望我们不需要导入aws-sdk/global,因为它本身未压缩的大小为206k。这对用户来说是很大的负担。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接