Невозможно загрузить PDF в корзину S3 через заранее назначенный URL-адрес, созданный из моего бэкэнда Node

Сценарий:

  1. Клиент (клиентский компонент Nextjs) запрашивает бэкэнд (конечную точку отдыха NextJS) для предварительно подписанного URL-адреса.
  2. Бэкэнд получает заданный URL-адрес для S3 через getSignedUrl
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
import { env } from "@/env";

const AWS_REGION = "ap-southeast-2";

const s3Client = new S3Client({
  region: AWS_REGION,
  credentials: {
    accessKeyId: env.AWS_S3_ACCESS_ID,
    secretAccessKey: env.AWS_S3_ACCESS_KEY,
  },
});

const command = new PutObjectCommand({
     Bucket: s3Object.bucket,
     Key: s3Object.key,
     // I also tried passing the contenttype here to see if it changed anything. But no it didn't.
     // ContentType: s3Object.contentType,
     // Might need more fields here to refine...
});

// Calculate dynamic expiration time based on file size, user's internet connection speed, etc.
const expiresIn = calculateExpirationTime(s3Object);

const presignedUrl = await getSignedUrl(s3Client, command, { expiresIn });

return presignedUrl;
  1. Клиент получает заранее назначенный URL-адрес от бэкэнда
  2. Клиент отправляет фрагмент файла на заранее заданный URL-адрес
// Uploads a chunk to the presigned URL
const uploadPart = (opts: {
  url: string;
  chunk: Blob;
  contentType: string;
  chunkSize: number;
  fileName: string;
  maxRetries: number;
}) =>
  fetch(opts.url, {
    method: "PUT",
    body: opts.chunk,
    //headers: {
    //  "Content-Type": opts.contentType,
    //},
  })
  1. Интерфейс выдает ошибку CORs:
Access to fetch at 'https://mybucket.s3.ap-southeast-2.amazonaws.com/mydoc.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AMZ_VALUE%2Fap-southeast-2%2Fs3%2Faws4_request&X-Amz-Date=20240516T010037Z&X-Amz-Expires=14400&X-Amz-Signature=SIGNATURE&X-Amz-SignedHeaders=host&x-id=PutObject' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Запрос OPTIONS отправляется и возвращается как 403 Forbidden

Request Method:
OPTIONS
Status Code:
403 Forbidden
Remote Address:
<IP>:443
Referrer Policy:
strict-origin-when-cross-origin

ЗАГОЛОВКИ ОТВЕТОВ:

Content-Type:
application/xml
Date:
Thu, 16 May 2024 01:03:33 GMT
Server:
AmazonS3
Transfer-Encoding:
chunked
X-Amz-Id-2:
<ID>
X-Amz-Request-Id:
<ID>

ЗАГОЛОВКИ ЗАПРОСОВ:

Accept:
*/*
Accept-Encoding:
gzip, deflate, br, zstd
Accept-Language:
en-US,en;q=0.9
Access-Control-Request-Method:
PUT
Cache-Control:
no-cache
Connection:
keep-alive
Host:
mybucket.s3.ap-southeast-2.amazonaws.com
Origin:
http://localhost:3000
Pragma:
no-cache
Referer:
http://localhost:3000/
Sec-Fetch-Dest:
empty
Sec-Fetch-Mode:
cors
Sec-Fetch-Site:
cross-site
User-Agent:
<AGENT>

Разрешения сегмента S3

Я настроил это правильно. Я пробовал много разных вариантов, включая явное определение localhost:3000 в файле AllowedOrigins.

Настройки CORS:

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET",
            "PUT",
            "POST",
            "DELETE",
            "HEAD"
        ],
        "AllowedOrigins": [
            "*"
        ]
    }
]

Политика, прикрепленная к пользователю

К пользователю, создающему заранее назначенный URL-адрес, прикреплена следующая политика:

  {
    "Version": "2012-10-17",
    "Statement": [
      {
        "Action": [
          "s3:GetObject",
          "s3:GetObjectVersion",
          "s3:PutObject"
        ],
        "Resource": [
          "arn:aws:s3:::mybucket",
          "arn:aws:s3:::bmybucket/*"
        ],
        "Effect": "Allow"
      }
    ]
  }

Я довольно долго боролся с этим и перепробовал множество предложений от SO и Google. Ни один из них не сработал. У меня такое чувство, что я упустил какую-то маленькую деталь, и это причиняет мне все это горе.

Обновление 1

Когда я тестирую команду PUT в Postman, я получаю следующую ошибку, которая отличается от ошибки COR:

<?xml version = "1.0" encoding = "UTF-8"?>
<Error>
    <Code>PermanentRedirect</Code>
    <Message>The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint.</Message>
    <Endpoint>s3.amazonaws.com</Endpoint>
    <Bucket>mybucket</Bucket>
    <RequestId>__ID__</RequestId>
    <HostId>__ID__</HostId>
</Error>

Проверьте, включен ли ACL или нет, «Разрешения» > «Владение объектом», здесь. Убедитесь, что вы включили «Владелец сегмента принудительно». это потому, что вам не нужно давать разрешения ACL.

Ravi Kyada 16.05.2024 07:57

@RaviKyada Я просто включил это, и это ничего не изменило.

James111 17.05.2024 06:21

@RaviKyada Я попробовал выполнить запрос в Postman и получил другую ошибку.

James111 17.05.2024 06:32
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
3
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Оказывается, я все сделал по инструкции, и все сводилось к тому, что я использовал неправильное имя корзины.

Мое развертывание CDK создало корзину с уникальным именем, и я использовал заданное мной имя. Однако я совершенно не заметил название корзины в своей консоли AWS.

Другие вопросы по теме