Я пытаюсь загрузить файлы в приватное хранилище S3 через ReactJs интерфейс с аутентификацией Cognito.
Для хранилища S3 установлены все значения по умолчанию, включая «заблокировать все публикации c доступ». CORS включен. Существует также политика IAM, предоставляющая пользователю Cognito пул Auth_Role с правами на чтение / запись для их папки корзины.
Я использую последнюю версию ampify (2.2.2) с конфигурацией:
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]"
}
};
Тогда в моем индексе. 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. Я не уверен, почему он возвращается к гостю, а затем не может подключиться к S3. Я следовал нескольким разным учебникам по загрузке S3, но все они приводят к одной и той же ошибке.
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}/*"
]
}
]
}
Эта политика IAM применяется к автоматически создаваемой роли IAM для пул пользователей Cognito, используемый интерфейсом React (Cognito_ [user_pool] Auth_Role).