【问题标题】:NodeJS Azure Storage returns 403NodeJS Azure 存储返回 403
【发布时间】:2018-08-13 13:14:15
【问题描述】:

我有一个访问 Azure 存储的 NodeJS API。 API 托管在带有 IISNode 的 Windows Server 2016、IIS 10.0 上。我正在使用 HapiJS 框架。

API 在 Azure 存储模拟器上运行良好,当我们转移到分阶段环境并将连接字符串更改为 azure 存储时,Azure 存储返回 403,禁止访问。

以下是记录信息:

[2018-03-05T16:06:36.257Z]debug : FINAL REQUEST OPTIONS:
{ uri: 'https://some-container.blob.core.windows.net:443/images?restype=container',
method: 'HEAD',
headers: 
   { 'x-ms-client-request-id': '2e2ea0a0-208f-11e8-9345-559bff0df7cf',
 'user-agent': 'Azure-Storage/2.7.0 (NODE-VERSION v9.5.0; Windows_NT 10.0.14393)',
 'x-ms-version': '2017-04-17',
 'x-ms-date': 'Mon, 05 Mar 2018 16:06:36 GMT',
 accept: 'application/atom+xml,application/xml',
 'Accept-Charset': 'UTF-8',
 'content-type': '',
 'content-length': 0,
 authorization: 'SharedKey container:someKeyHere' },
mode: 'disable-fetch',
encoding: undefined,
timeout: 120000,
forever: true }

[2018-03-05T16:06:37.188Z]debug : RESPONSE:
{ error: 
   { StorageError: Forbidden
at Function.StorageServiceClient._normalizeError (C:\Load2.0\Staged\Backend\node_modules\azure-storage\lib\common\services\storageserviceclient.js:1191:23)
at BlobService.StorageServiceClient._processResponse (C:\Load2.0\Staged\Backend\node_modules\azure-storage\lib\common\services\storageserviceclient.js:738:50)
at Request.processResponseCallback [as _callback] (C:\Load2.0\Staged\Backend\node_modules\azure-storage\lib\common\services\storageserviceclient.js:311:37)
at Request.self.callback (C:\Load2.0\Staged\Backend\node_modules\azure-storage\node_modules\request\request.js:188:22)
at Request.emit (events.js:160:13)
at Request.<anonymous> (C:\Load2.0\Staged\Backend\node_modules\azure-storage\node_modules\request\request.js:1171:10)
at Request.emit (events.js:160:13)
at IncomingMessage.<anonymous> (C:\Load2.0\Staged\Backend\node_modules\azure-storage\node_modules\request\request.js:1091:12)
at Object.onceWrapper (events.js:255:19)
at IncomingMessage.emit (events.js:165:20)
at endReadableNT (_stream_readable.js:1101:12)
at process._tickCallback (internal/process/next_tick.js:152:19)
 name: 'StorageError',
 message: 'Forbidden',
 code: 'Forbidden',
 statusCode: 403,
 requestId: '2354daf1-001e-007c-25ac-b48832000000' },
  response: 
   { isSuccessful: false,
 statusCode: 403,
 body: '',
 headers: 
  { 'transfer-encoding': 'chunked',
    server: 'Microsoft-HTTPAPI/2.0',
    'x-ms-request-id': '2354daf1-001e-007c-25ac-b48832000000',
    date: 'Mon, 05 Mar 2018 18:06:36 GMT' },
 md5: undefined } }

我不知道为什么会得到 403,我从 Azure 门户复制了连接字符串并多次检查。

下面是我正在使用的源代码:

const azureStorage = require("azure-storage");
const shortId = require("shortid");

class AzureBlobService {
    constructor(connectionString){
        this.connectionString = connectionString;
        this.blobService = azureStorage.createBlobService(this.connectionString);
    }

    /**
     * Upload a file
     * @param {*} fileBuffer 
     * @param {*} filename
     * @param {*} container
     * @param {*} callback
     */
    uploadFile(fileBuffer, filename, container, callback) {
        let fileExtension = filename.slice((filename.lastIndexOf(".") - 1 >>> 0) + 2);
        this.blobService.createContainerIfNotExists(containerToUse, err => {
            if (err) {
                callback(err, { message: "Failed to create blob container" });
            } else {
                let blobName = shortId.generate() + "." + fileExtension;
                this.blobService.createBlockBlobFromStream(containerToUse, blobName, 
                this._bufferToStream(fileBuffer), fileBuffer.length, err => {
                if (err) {
                    callback(err, { message: "Failed to upload blob" });
                } else {
                    let sasToken = this.blobService.generateSharedAccessSignature(containerToUse, blobName, 
                        { AccessPolicy: { Expiry: azureStorage.date.minutesFromNow(10) } });
                        let sasUrl = this.blobService.getUrl(containerToUse, blobName, sasToken, true);

                        // TODO: return URL
                        callback(null, { url: sasUrl, blobName: blobName });
                    }
                });
            }
        });
    }

    /**
     * Convert a buffer to stream
     * @param {*} buffer 
     */
    _bufferToStream(buffer) {
        let stream = new Duplex();
        stream.push(buffer);
        stream.push(null);
        return stream;
    }
}

【问题讨论】:

  • 你多次复制了什么?您是否使用了门户提供的正确 Blob 存储访问密钥?
  • @ethane 连接字符串。我已经更新了错字。
  • 也请分享您的代码。
  • 谢谢。你的代码对我来说看起来不错。您可以检查运行此代码的服务器上的时间吗?除了不正确的密钥外,时钟偏差是可能导致此 403 错误的另一个原因。
  • @GauravMantri 非常感谢,您值得喝啤酒。服务器上设置的时间与时区不同。我与互联网时间同步,一切正常。

标签: node.js azure azure-storage hapijs


【解决方案1】:

对于 azure-storage-node,您可以通过帐户密钥或 SAS 令牌创建 blobService 对象。例如,使用从 Azure 门户生成的存储帐户密钥时:

var blobService = azureStorage.createBlobService(accountName, accountKey).withFilter(new azureStorage.ExponentialRetryPolicyFilter());

blobService.logger = new azureStorage.Logger();
blobService.createContainerIfNotExists('1mycontainer', function (err, res) {
  if (!err) {
    blobService.createBlockBlobFromLocalFile('1mycontainer', 'taskblob', 'task1.txt', function (error, result, response) {
      if (!error) {
          console.log("uploaded");
      } else {
          console.log(error);
      }
    }); 
  }
});

【讨论】:

  • 我使用 Azure 门户中的帐户密钥进行了尝试,但仍然出现相同的错误。 403,禁止。
猜你喜欢
  • 2017-02-14
  • 2017-09-06
  • 1970-01-01
  • 1970-01-01
  • 2018-05-17
  • 1970-01-01
  • 1970-01-01
  • 2014-09-03
  • 1970-01-01
相关资源
最近更新 更多