reactjs - React AWS Amplify S3 Storage.put() No Credentials 错误

标签 reactjs amazon-s3 aws-amplify

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

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

我正在使用带有配置的最新版本的放大(2.2.2):

配置.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);
  }

}

这会引发一 strip 有“无凭据”消息的警报。我启用了调试,控制台日志如下:
[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

它正在查找有效的 session 和凭据。我没有使用任何联合身份或提供者,只使用 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 用户池 (Cognito_[user_pool]Auth_Role) 自动创建的 IAM 角色。

最佳答案

线程是旧的,但是,我仍然把我找到的解决方案放在这个问题上。
我在尝试安装 S3 时收到“NoCredentails 错误”。
我正在使用 Amplify:4.50.2,使用 a: >amplify add auth 添加了一个身份验证。
发现问题是我的 Cognito 缺少身份池,但 Amplify 成功创建了用户池。
问题发生是因为我选择了选项:手动配置,同时添加了身份验证。
我通过删除现有的身份验证解决了这个问题:
运行:>amplify auth remove
并添加了一个新的并在添加过程中选择了“默认配置”选项:
$amplify 添加授权
默认配置(选择此项)
社交提供者(联盟)的默认配置
手动配置
我想了解更多。

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

关于reactjs - React AWS Amplify S3 Storage.put() No Credentials 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59853347/

相关文章:

reactjs - 找不到模块 : Can't resolve 'http2' when importing firebase-admin

javascript - 向 React Leaflet map 添加标题

amazon-web-services - 如何连接到 Amazon Redshift 或 Apache Spark 中的其他数据库?

java - 从java aws lambda访问s3

css - 如何从 Angular/Amplify/Cognito 登录页面删除 "Sign in with AWS"按钮?

node.js - 放大初始化错误 - ✖ 根堆栈创建失败初始化失败 TypeError : Cannot redefine property: default

reactjs - 将方法作为 Prop 传递给所有 child

javascript - Amazon S3 上传图像 - 跟踪上传进度 - Angular JS

graphql - Appsync 和 GraphQL : how to filter a list by nested value

reactjs - 控制台记录导入的 SVG 给出数字