#javascript #azure #azure-blob-storage
Вопрос:
Что я пытаюсь сделать: у меня есть клиентская сторона (браузер, не node.js) JS-приложение, которое загружает файлы в хранилище больших двоичных объектов вместе с @azure/storage-blob
пакетом. Для этого он извлекает маркер SAS из функции Azure для определенного большого двоичного объекта. Большой двоичный объект создается Функцией при каждом запросе, и клиенту возвращается токен SAS. Генерация больших двоичных объектов и SAS работает, и я могу загрузить ее, когда URL-адрес большого двоичного объекта с SAS открывается в браузере.
Теперь что не работает, так это когда я пытаюсь подключиться с помощью SAS большого двоичного объекта (не SAS учетной записи хранения или строки подключения) к учетной записи хранения. Приведенный ниже код работает при использовании с SAS из всей учетной записи хранения, но я не хочу давать столько разрешений. Я не понимаю, почему токен SAS может быть создан для определенного большого двоичного объекта, если к нему невозможно подключиться через клиент службы больших двоичных объектов.
Можно создать токен SAS, доступный только для чтения, для всей учетной записи хранения, чтобы запустить и запустить соединение. Но куда после этого отправится SAS-объект Blob, чтобы к нему можно было получить доступ?
Есть что-то фундаментальное, чего мне, кажется, не хватает, так как же этого можно достичь?
const url = `https://${storageName}.blob.core.windows.net/${sasToken}`; // sas for blob from the azure function
// const url = `https://${storageName}.blob.core.windows.net${containerSas}`; // sas from container
// const url = `https://${storageName}.blob.core.windows.net/${containerName}/${fileName}${sasToken}`; // does not work either
const blobService = new BlobServiceClient(url);
await this.setCors(blobService);
// get Container
const containerClient: ContainerClient = blobService.getContainerClient(containerName);
// get client
const blobClient = containerClient.getBlockBlobClient(fileName);
const exists = await blobClient.exists();
console.log('Exists', exists);
// set mimetype as determined from browser with file upload control
const options: BlockBlobParallelUploadOptions = { blobHTTPHeaders: { blobContentType: file.type } };
// upload file
await blobClient.uploadBrowserData(file, options);
Редактировать:
Маркер SAS для большого двоичного объекта: ?sv=2018-03-28amp;sr=bamp;sig=somesecretamp;se=2021-07-04T15:14:28Zamp;sp=racwl
Метод CORS, хотя я могу подтвердить, что он работает, когда я использую глобальную учетную запись хранилища SAS:
private async setCors(blobService: BlobServiceClient): Promise<void> {
var props = await blobService.getProperties();
props.
cors =
[{
allowedOrigins: '*',
allowedMethods: '*',
allowedHeaders: '*',
exposedHeaders: '*',
maxAgeInSeconds: 3600
}]
;
}
Ошибки:
При использовании SAS Blob-объектов с помощью метода setCors/GetProperties: 403 (Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.)
При использовании следующего URL-адреса службы в методе setCors/GetProperties: https://${storageName}.blob.core.windows.net/${containerName}/${fileName}${sasToken}
=> RestError: The resource doesn't support specified Http Verb.
При использовании учетной записи хранения SAS с разрешениями только на ЧТЕНИЕ при доступе к большому двоичному объекту (blob.существует()): 403 (This request is not authorized to perform this operation using this resource type.)
(имеет смысл, но тогда я хотел бы использовать SAS для конкретного большого двоичного объекта)
Комментарии:
1. Несколько вопросов: 1) Можете ли вы поделиться тем, как выглядит ваш токен SAS? Вы можете запутать
sig
часть токена. 2) Когда вы говорите «это не работает», не могли бы вы, пожалуйста, уточнить это? Какая часть кода дает сбой? и 3) Пожалуйста, укажите кодsetCors
метода. Пожалуйста, отредактируйте свой вопрос и предоставьте эту информацию.
Ответ №1:
Причина, по которой вы столкнулись с этой ошибкой, заключается в том, что вы пытаетесь установить CORS с помощью токена SAS, созданного для большого двоичного объекта (который является a Service SAS
). Операция CORS-это операция уровня обслуживания, и для этого вам необходимо использовать токен SAS, полученный на уровне учетной записи. Другими словами, вам нужно будет использовать an Account SAS
. Любой токен SAS, созданный для контейнера или большого двоичного объекта, является Service SAS
токеном.
Сказав это, вам действительно не нужно устанавливать свойства CORS для учетной записи хранения в каждом запросе. Это то, что вы можете сделать во время создания учетной записи.
Как только вы удалите вызов setCors
метода из своего кода, он должен работать нормально.
Учитывая, что вы работаете только с SAS большого двоичного объекта, вы можете значительно упростить свой код, создав экземпляр BlockBlobClient
непосредственно с использованием URL-адреса SAS. Например, ваш код может быть таким простым, как:
const url = `https://${storageName}.blob.core.windows.net/${containerName}/${fileName}${sasToken}`;
const blobClient = new BlockBlobClient(url);
//...do operations on blob using this blob client
Комментарии:
1. Это сработало идеально, спасибо. Из всех примеров и документации не было ясно, что я мог пропустить CORS и напрямую вызвать BlobClient