Не удаётся загрузить файлы через Iconik API. Подпись не совпадает. Доступ запрещён.

Вопрос или проблема

Не удалось загрузить файлы через Iconik API SignatureDoesNotMatchДоступDenied.

Я пытаюсь создать базовую функцию Node.js для загрузки файла в iconik; после выполнения функции я успешно создаю актив, получаю идентификатор хранилища, создаю формат, создаю набор файлов, но затем возникает ошибка при попытке использовать uploadURL для загрузки самого файла. Я вижу созданный актив в веб-интерфейсе iconik.

const uploadToIconik = async () => {
    try {
        const createAssetResponse = await axios.post(`${ICONIK_API_URL}/assets/v1/assets/`, {title: fileName}, {headers: headersIconik});
        const assetId = createAssetResponse.data.id;
        console.log('#########################################################################');
        console.log('###########################################################################');
        console.log('## 1 из 7: Актив создан:', assetId);

        const storageResponse = await axios.get(`${ICONIK_API_URL}/files/v1/storages/matching/FILES/`, {headers: headersIconik});
        const storageId = storageResponse.data.id;
        console.log('## 2 из 7: Идентификатор хранилища:', storageId);

        const formatResponse = await axios.post(`${ICONIK_API_URL}/files/v1/assets/${assetId}/formats/`, {
            user_id: userID, 
            name: "ORIGINAL",
            metadata: [{ internet_media_type: "video/mp4" }],
            storage_methods: ["GCS"]
        }, {
            headers: headersIconik
        });
        const formatId = formatResponse.data.id;
        console.log('## 3 из 7: Формат создан:', formatId);

        const fileSetResponse = await axios.post(`${ICONIK_API_URL}/files/v1/assets/${assetId}/file_sets/`, {
            format_id: formatId,
            storage_id: storageId,
            base_dir: "/",
            name: fileName,
            component_ids: []
        }, {
            headers: headersIconik
        });
        const fileSetId = fileSetResponse.data.id;
        console.log('## 4 из 7: Набор файлов создан:', fileSetId);

        const fileCreateResponse = await axios.post(`${ICONIK_API_URL}/files/v1/assets/${assetId}/files/`, {
            original_name: fileName,
            size: fileSize,
            format_id: formatId,
            file_set_id: fileSetId,
            storage_id: storageId,
            type: 'FILE',
            metadata: {},
            directory_path: ""
        }, {
            headers: headersIconik
        });
        const uploadUrl = fileCreateResponse.data.upload_url;
        const fileId = fileCreateResponse.data.id;
        console.log('## 5 из 7: URL загрузки:', uploadUrl);

        // 6. Загрузка файла
        //const fileData = fs.readFileSync(filePath);
        const fileStream = fs.createReadStream(filePath);
        console.log('## 6 из 7: Длина содержимого: '+ fileSize);
        await axios.put(uploadUrl, fileStream, {
            headers: {
                'Content-Type': 'application/octet-stream',
                'x-goog-resumable':'start',
                'Content-Length':fileSize
            }
        });

        console.log('## 6 из 7: Файл успешно загружен!');

        // 7. Завершение задачи
        await axios.patch(`${ICONIK_API_URL}/files/v1/assets/${assetId}/files/${fileId}/`, {
            status: "CLOSED",
            progress_processed: 100
        }, {
            headers: headersIconik
        });
        console.log('## 7 из 7: Загрузка завершена.');

    } catch (error) {
        // await axios.delete(`${ICONIK_API_URL}/files/v1/assets/${assetId}/uploads/`,{ 
        //     headers: headersIconik
        // });

        console.error('Ошибка при загрузке файла:', error.response ? error.response.data : error.message);
    }
};

Логи консоли:

src % node iconik.js
1 из 7: Актив создан: fb8bca28-7777-11ef-847c-9a75db8955fe
2 из 7: Идентификатор хранилища: aaba2964-0a29-11ec-99e0-0a580a3c0e44
3 из 7: Формат создан: fc22dfee-7777-11ef-99b2-4219142fab38
4 из 7: Набор файлов создан: fc41c47c-7777-11ef-8c97-2a655031b7bd
5 из 7: URL загрузки: https://storage.googleapis.com/iconik-us-files/a

Шаг 6 завершился неудачей с следующей ошибкой при запуске URL загрузки, предоставленного самим API.

Ошибка загрузки файла: <?xml version='1.0' encoding='UTF-8'?><Error><Code>SignatureDoesNotMatch</Code><Message>Доступ запрещен.</Message><Details>Подпись запроса, которую мы вычислили, не совпадает с предоставленной вами подписью. Проверьте ваш секретный ключ Google и способ подписи.</Details><StringToSign>POST

Любая помощь будет очень приветствоваться. Спасибо всем заранее.

Я пробовал все в соответствии с документацией iconik, но не знаю, нужно ли авторизоваться через OAuth2 или достаточно этого метода, который я пытаюсь использовать, просто с ID приложения и токеном приложения, которые я получил из настроек iconik.

Ответ или решение

Проблема, с которой вы столкнулись, связана с ошибкой SignatureDoesNotMatch при попытке загрузки файла через API Iconik. Это свидетельствует о несоответствии сигнатуры, связанной с вашим запросом и тем, как Google Cloud Storage ожидает ее. Давайте разберем шаги, которые могут помочь решить эту проблему.

Шаги для устранения проблемы

  1. Проверка URL загрузки: Убедитесь, что uploadUrl, который вы получаете от API Iconik, корректный и действительно относится к ресурсу Google Cloud Storage. Вы можете скопировать uploadUrl и попробовать открыть его в браузере. Если бы он был недоступен, вы бы увидели другую ошибку.

  2. Параметры заголовков: Убедитесь, что заголовки, которые вы передаете в запросе на загрузку, включают все необходимые атрибты. Похоже, вы передаете только Content-Type и x-goog-resumable. Некоторые API могут требовать дополнительных заголовков, таких как Authorization или специальные заголовки, специфичные для Google Cloud Storage.

  3. Метод аутентификации:

    • Если вы используете APP ID и APP TOKEN, убедитесь, что они правильно настроены для доступа к вашему ресурсу. Иногда может понадобиться использовать OAuth2 для более безопасной аутентификации.
    • Проверьте, имеете ли вы все необходимые разрешения для записи в указанный bucket в Google Cloud Storage (GCS).
  4. Правильная инициализация запроса:
    • Убедитесь, что вы прежде чем пытаться загрузить файл, действительно инициируете загрузку как "resumable". В вашем коде вы не указали x-goog-resumable: start в части инициализации.
    • Убедитесь, что файл, который вы загружаете, действительно доступен и имеет правильный путь.

Вот небольшое переосмысление части вашего кода, которое может помочь:

// 6. Upload File
const fileStream = fs.createReadStream(filePath);
console.log('## 6 of 7: Content-Length: ' + fileSize);

// Инициализируем загрузку
await axios.put(uploadUrl, fileStream, {
    headers: {
        'Content-Type': 'application/octet-stream',
        'x-goog-resumable': 'start',
        'Content-Length': fileSize,
        'Authorization': `Bearer ${process.env.GOOGLE_API_TOKEN}`  // Если необходимо
    }
});
  1. Просмотр ответа от GCS: Если ошибка сохраняется, проверьте полное сообщение об ошибке – возможно, есть дополнительные подсказки, указывающие на точную причину проблемы.

Резюме

Следуйте вышеперечисленным шагам, чтобы убедиться, что все параметры и настройки передаются правильно. Если возникнут дополнительные проблемы, проверьте настройки вашего проекта в Google Cloud и убедитесь, что вы используете нужные токены и права доступа. Если требуется, вы можете также изменить способ аутентификации на OAuth2 для обеспечения более безопасного доступа.

Если проблема не решается, будьте готовы предоставить более подробную информацию о ваших настройках API и использовании токенов для дальнейшего анализа.

Оцените материал
Добавить комментарий

Капча загружается...