React AWS Amplify S3 Storage.put()没有凭证错误

时间:2020-01-22 05:49:36

标签: reactjs amazon-s3 aws-amplify

我正在尝试通过具有Cognito身份验证的ReactJs前端将文件上传到私有S3存储桶。

S3存储桶是所有默认值,包括选中“禁止所有公共访问”。启用了CORS。还有一个IAM策略,授予认知用户池Auth_Role对存储桶文件夹的读/写权限。

我正在使用最新版本的amplify(2.2.2)和config:

config.js

export default {
  apiGateway: {
    REGION: "ap-southeast-2",
    URL: "https://myapi.execute-api.ap-southeast-2.amazonaws.com/Development"
  },
  s3: {
    REGION: "ap-southeast-2",
    BUCKET: "[Bucket_Name]"
  },
  cognito: {
    REGION: "ap-southeast-2",
    USER_POOL_ID: "ap-southeast-2_[ID]",
    AUTH_URL:
      "https://mysite.auth.ap-southeast-2.amazoncognito.com/login/",
    APP_CLIENT_ID: "[APP_CLIENT_ID]"
  }
};

然后在我的index.js中:

import Amplify from "aws-amplify";

// ENABLE DEBUG MODE
window.LOG_LEVEL = "DEBUG";
Amplify.configure({
  Auth: {
    mandatorySignIn: true,
    region: config.cognito.REGION,
    userPoolId: config.cognito.USER_POOL_ID,
    identityPoolId: config.cognito.IDENTITY_POOL_ID,
    userPoolWebClientId: config.cognito.APP_CLIENT_ID,
    cognitoAuthUrl: config.cognito.AUTH_URL,
    cognitoRedirectUrl: config.cognito.REDIRECT_URL
  },
  Storage: {
    region: config.s3.REGION,
    bucket: config.s3.BUCKET,
    identityPoolId: config.cognito.IDENTITY_POOL_ID
  },
  API: {
    endpoints: [
      {
        name: "MyAPI-Dev",
        endpoint: config.apiGateway.URL,
        region: config.apiGateway.REGION,
        authenticationType: "AMAZON_COGNITO_USER_POOLS",
        custom_header: async () => {
          return {
            "Access-Control-Allow-Origin": "*"
          };
        }
      }
    ]
  }
});

最后,我有一个<input type="file" />调用的标准storage.put()元素:

const handleSubmit = async e => {
  var currentFile = e.target.files[0]; // there is only one file input for now
  var customPrefix = `user_uploads/`; // Custom prefix for the file upload matching IAM policy

// This should upload the file to "user_uploads/{cognito_id}/{filename}
  try{
    var result = await Storage.put(currentFile.name, currentFile , {
      contentType: currentFile.type,
      level: "private",
      customPrefix: customPrefix 
    });

    console.log(result);
  } catch (e) {
    alert(e.message);
  }

}

这会引发一条警告,提示消息“没有凭据”。我启用了调试,控制台日志如下:

[DEBUG] 43:07.911 Credentials - getting credentials 
[DEBUG] 43:07.912 Credentials - picking up credentials 
[DEBUG] 43:07.912 Credentials - getting new cred promise 
[DEBUG] 43:07.913 Credentials - checking if credentials exists and not expired 
[DEBUG] 43:07.913 Credentials - need to get a new credential or refresh the existing one 
[DEBUG] 43:07.915 AuthClass - Getting current user credentials 
[DEBUG] 43:07.917 AuthClass - Getting current session 
[DEBUG] 43:07.918 AuthClass - Getting the session from this user: 
Object { username: "2a[GUID]0cf", pool: {…}, Session: null, client: {…}, signInUserSession: {…}, authenticationFlowType: "USER_SRP_AUTH", storage: Storage, keyPrefix: "CognitoIdentityServiceProvider.5a[ID]ci", userDataKey: "CognitoIdentityServiceProvider.5a[ID]ci.2a[GUID]0cf.userData", attributes: {…}, … }
[DEBUG] 43:07.921 AuthClass - Succeed to get the user session 
Object { idToken: {…}, refreshToken: {…}, accessToken: {…}, clockDrift: 2 }
[DEBUG] 43:07.922 AuthClass - getting session success 
Object { idToken: {…}, refreshToken: {…}, accessToken: {…}, clockDrift: 2 }
[DEBUG] 43:07.924 Credentials - set credentials from session 
[DEBUG] 43:07.924 Credentials - No Cognito Federated Identity pool provided 
[DEBUG] 43:07.925 AuthClass - getting session failed No Cognito Federated Identity pool provided
[DEBUG] 43:07.926 Credentials - setting credentials for guest
[WARN] 43:07.926 AWSS3Provider - ensure credentials error cannot get guest credentials when mandatory signin enabled

正在查找有效的会话和凭据。我不使用任何联合身份或提供商(仅Cognito本身)。我不确定为什么它会退回到Guest,然后无法连接到S3。我遵循了一些不同的S3上传教程,但是它们都导致相同的错误。

编辑: IAM政策:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ListYourObjects",
            "Effect": "Allow",
            "Action": "s3:ListBucket",
            "Resource": [
                "arn:aws:s3:::[bucket_name]"
            ],
            "Condition": {
                "StringLike": {
                    "s3:prefix": [
                        "user_uploads/${cognito-identity.amazonaws.com:sub}"
                    ]
                }
            }
        },
        {
            "Sid": "ReadWriteDeleteYourObjects",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::[bucket_name]/user_uploads/${cognito-identity.amazonaws.com:sub}",
                "arn:aws:s3:::[bucket_name]/user_uploads/${cognito-identity.amazonaws.com:sub}/*"
            ]
        }
    ]
}

此IAM策略适用于为React前端(Cognito_ [user_pool] Auth_Role)使用的cognito用户池自动创建的IAM角色。

2 个答案:

答案 0 :(得分:1)

您没有设置身份池ID。您需要用户池和身份池。

如果您没有,请进入“联合身份”选项卡,然后单击“创建”按钮。

“身份验证”提供程序将您的用户池ID和应用程序客户端ID添加到“认知”标签中。

这还将在您将策略附加到的IAM中创建Cognito_ [Identity Provider Name] Auth_Role角色。

答案 1 :(得分:1)

线程很旧,但我仍然把我找到的解决方案放在这个问题上。

我在尝试安装 S3 时收到“NoCredentails 错误”。 我正在使用 Amplify : 4.50.2,使用 a: >amplify add auth 添加了一个身份验证。

发现问题是我的 Cognito 缺少身份池,但 Amplify 成功创建了用户池。 问题发生是因为我选择了选项:手动配置,同时添加身份验证。

我通过删除现有身份验证解决了这个问题:
运行:>amplify auth remove 并添加了一个新的并在添加过程中选择了“默认配置”选项:
$amplify 添加身份验证
默认配置(选择此项)
Social Provider(联盟)的默认配置
手动配置
我想了解更多。


执行放大推送后,请确保创建了用户池和身份池。 希望它可以帮助一些有类似问题的人。