简体   繁体   中英

React AWS Amplify S3 Storage.put() No Credentials error

I am trying to upload files to a private S3 bucket through a ReactJs front-end with Cognito auth.

The S3 bucket is all defaults including "block all public access" checked. CORS is enabled. There is also an IAM policy giving the cognito user pool Auth_Role read/write permissions on their folder of the bucket.

I am using the latest version of amplify (2.2.2) with the 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]"
  }
};

Then in my 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": "*"
          };
        }
      }
    ]
  }
});

Finally I have a standard <input type="file" /> element with the storage.put() call:

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);
  }

}

This throws up an alert with the message "No credentials". I enabled debugging and the console log is the following:

[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

It is finding a valid session and credentials. I am not using any Federated Identities or providers only Cognito itself. I am not sure why it is falling back to Guest and then failing to connect to S3. I have followed a few different S3 upload tutorials but they all result in the same error.

edit: IAM Policy:

{
    "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}/*"
            ]
        }
    ]
}

This IAM policy is applied to the automatically created IAM role for the cognito user pool used by the React front end (Cognito_[user_pool]Auth_Role).

The thread is old, but still , I am putting the solution I found to this problem.

I was getting the "NoCredentails error" while trying to put on S3. I am using Amplify : 4.50.2, added an auth using a: >amplify add auth.

The issue was found to be that my Cognito was missing an Identity Pool, but the user pool was created successfully by Amplify. The issue happenend because I chose the option : Manual Configuration, while adding an auth.

I resolved this issue by removing existing auth:
Run : >amplify auth remove And added a new one and chose the "Default Configuration" option during add:
$amplify add auth
Default configuration (Choose this)
Default configuration with Social Provider (Federation)
Manual configuration
I want to learn more.


After doing amplify push, make sure that the user pool and identity pool are created. Hope it helps some one having similar issue.

You don't have an identity pool id set. You need both a user pool and an identity pool.

If you don't have one, in cognito go to the Federated Identities tab and click the create button.

Under Authentication providers add your user pool id and app client id in the Cognito tab.

This will also create the Cognito_[Identity Provider Name]Auth_Role role in IAM that you attach your policy to.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM