
# 使用临时URL进行授权访问(Node.js SDK)
![](https://support.huaweicloud.com/sdk-nodejs-devg-obs/public_sys-resources/notice_3.0-zh-cn.png)
开发过程中，您有任何问题可以在GitHub上[提交issue](https://github.com/huaweicloud/huaweicloud-sdk-nodejs-obs/issues)，或者在[华为云对象存储服务论坛](https://bbs.huaweicloud.com/forum/forum-620-1.html)中发帖求助。
#### 功能说明
通过访问密钥、请求方法类型、请求参数等信息生成一个在Query参数中携带鉴权信息的URL，可将该URL提供给其他用户进行临时访问。在生成URL时，需要指定URL的有效期来限制访客用户的访问时长。
如果想授予其他用户对桶或对象临时进行其他操作的权限（例如上传或下载对象），则需要生成带对应请求的URL后（例如生成上传对象PUT请求的URL），将该URL提供给其他用户。
#### 接口约束
- OBS支持的Region与Endpoint的对应关系，详细信息请参见[地区与终端节点](https://console.huaweicloud.com/apiexplorer/#/endpoint/OBS)。

- 如果遇到跨域报错、签名不匹配问题，请参考以下步骤排查问题：
  1. 未配置跨域，需要在控制台配置CORS规则，请参考[配置桶允许跨域请求](https://support.huaweicloud.com/sdk-browserjs-devg-obs/obs_24_0107.html)。
  
  2. 签名计算问题，请参考[URL中携带签名](https://support.huaweicloud.com/api-obs/obs_04_0011.html)排查签名参数是否正确；比如上传对象功能，后端将Content-Type参与计算签名生成授权URL，但是前端使用授权URL时没有设置Content-Type字段或者传入错误的值，此时会出现跨域错误。解决方案为：Content-Type字段前后端保持一致。
   
 
#### 方法定义
```
ObsClient.createSignedUrlSync(params)
```
#### 请求参数
表1请求参数列表 
| **参数名称**     | **参数类型**                                         | **是否必选** | **描述**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
|:---|:---|:---|:---|
| Method       | [HttpMethodType] | 必选       | **参数解释：** HTTP方法类型，详情参见[HttpMethodType]。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| Bucket       | string                                           | 必选       | **参数解释** **：** 桶名。 **约束限制：** - 桶的名字需全局唯一，不能与已有的任何桶名称重复，包括其他用户创建的桶。  - 桶命名规则如下： - 3～63个字符，数字或字母开头，支持小写字母、数字、"-"、"."。  - 禁止使用IP地址。  - 禁止以"-"或"."开头及结尾。  - 禁止两个"."相邻（如："my..bucket"）。  - 禁止"."和"-"相邻（如："my-.bucket"和"my.-bucket"）。    - 同一用户在同一个区域多次创建同名桶不会报错，创建的桶属性以第一次请求为准。   **取值范围：** 长度为3～63个字符。 **默认取值：** 无 |
| Key          | string                                           | 必选       | **参数解释：** 对象名。对象名是对象在存储桶中的唯一标识。对象名是对象在桶中的完整路径，路径中不包含桶名。 例如，您对象的访问地址为examplebucket.obs.cn-north-4.myhuaweicloud.com/folder/test.txt 中，对象名为folder/test.txt。 **约束限制：** 无 **取值范围：** 长度大于0且不超过1024的字符串。 **默认取值：** 无                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| SpecialParam | [SpecialParam]  | 可选       | **参数解释：** 要访问的子资源。 **约束限制：** 无 **取值范围：** 详情参见[SpecialParam]。 **默认取值：** 无                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| Expires      | number                                           | 可选       | **参数解释：** 带授权信息的URL的过期时间。 **约束限制：** 无 **取值范围：** - 临时密钥取值范围为0\~86400秒。  - 永久密钥取值范围为0\~630720000秒。   **默认取值：** 300                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| Headers      | object                                           | 可选       | **参数解释：** 请求中携带的头域。 **约束限制：** 无 **取值范围：** 无 **默认取值：** 无                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| QueryParams  | object                                           | 可选       | **参数解释：** 请求中携带的查询参数。 **约束限制：** 无 **取值范围：** 无 **默认取值：** 无                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
   
 表2HttpMethodType 
| **常量值** | **说明**          |
|:---|:---|
| GET     | HTTP GET请求。     |
| POST    | HTTP POST请求。    |
| PUT     | HTTP PUT请求。     |
| DELETE  | HTTP DELETE请求。  |
| HEAD    | HTTP HEAD请求。    |
| OPTIONS | HTTP OPTIONS请求。 |
   
 表3SpecialParam 
| **常量值**       | **适用接口**              |
|:---|:---|
| storagePolicy | 设置/获取桶存储类型。           |
| quota         | 设置/获取桶配额。             |
| storageinfo   | 获取桶存量信息。              |
| location      | 获取桶区域位置。              |
| acl           | 设置/获取桶ACL、设置/获取对象ACL。 |
| policy        | 设置/获取/删除桶策略。          |
| cors          | 设置/获取/删除桶CORS配置。      |
| versioning    | 设置/获取桶多版本状态。          |
| website       | 设置/获取/删除桶Website配置。   |
| logging       | 设置/获取桶日志管理配置。         |
| lifecycle     | 设置/获取/删除桶生命周期配置。      |
| notification  | 设置/获取桶时间通知配置。         |
| tagging       | 设置/获取/删除桶标签。          |
| append        | 追加上传对象                |
| delete        | 批量删除对象。               |
| versions      | 列举桶内多版本对象。            |
| uploads       | 列举桶内分段上传任务、初始化分段上传任务。 |
| restore       | 恢复归档存储或深度归档存储对象。      |
   
#### 返回结果
表4返回结果 
| **参数名称**                   | **参数类型** | **描述**                                                                                |
|:---|:---|:---|
| SignedUrl                  | string   | **参数解释：** 带授权信息的URL。              |
| ActualSignedRequestHeaders | object   | **参数解释：** 通过带授权信息的URL发起请求时实际应携带的头域。 |
   
通过OBS Node.js SDK生成临时URL访问OBS的步骤如下：
1. 通过ObsClient.createSignedUrlSync生成带签名信息的URL。
2. 使用任意HTTP库发送HTTP/HTTPS请求，访问OBS服务。
![](https://support.huaweicloud.com/sdk-nodejs-devg-obs/public_sys-resources/caution_3.0-zh-cn.png)
如果遇到跨域报错、签名不匹配问题，请参考以下步骤排查问题：
1. 未配置跨域，需要在控制台配置CORS规则，请参考[配置桶允许跨域请求](https://support.huaweicloud.com/sdk-browserjs-devg-obs/obs_24_0107.html)。
2. 签名计算问题，请参考[URL中携带签名](https://support.huaweicloud.com/api-obs/obs_04_0011.html)排查签名参数是否正确；比如上传对象功能，后端将Content-Type参与计算签名生成授权URL，但是前端使用授权URL时没有设置Content-Type字段或者传入错误的值，此时会出现跨域错误。解决方案为：Content-Type字段前后端保持一致。
 
以下代码示例展示了如何使用临时URL进行授权访问，包括：创建桶、上传对象、下载对象、列举对象、删除对象。
#### 代码示例一：创建桶
本示例用于使用临时URL授权创建桶。
```
// 引入obs库
// 使用npm安装
var ObsClient = require('esdk-obs-nodejs');
// 使用源码安装
// var ObsClient = require('./lib/obs');
var https = require('https');
var urlLib = require('url');
var crypto = require('crypto');
// 创建ObsClient实例
var obsClient = new ObsClient({
       // 推荐通过环境变量获取AKSK，这里也可以使用其他外部引入方式传入，如果使用硬编码可能会存在泄露风险
       // 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
       access_key_id: process.env.ACCESS_KEY_ID,
       secret_access_key: process.env.SECRET_ACCESS_KEY,
       server : 'https://your-endpoint'
});
let bucketName = 'bucketname';
let method = 'PUT';
let res = obsClient.createSignedUrlSync({Method : method, Bucket : bucketName});
let location = 'your-location';
let content  = `<CreateBucketConfiguration><LocationConstraint>${location}</LocationConstraint></CreateBucketConfiguration>`;
// 使用PUT请求创建桶
var url = urlLib.parse(res.SignedUrl);
var req = https.request({
       method : method,
       host : url.hostname,
       port : url.port,
       path : url.path,
       rejectUnauthorized : false,
       headers : res.ActualSignedRequestHeaders || {}
});
console.log('Creating bucket using url:' + res.SignedUrl);
req.on('response',   (serverback) => {
       var buffers = [];
       serverback.on('data', (data) => {
              buffers.push(data);
       }).on('end', () => {
              
              if(serverback.statusCode < 300){
                     console.log('Creating bucket using temporary signature succeed.');
              }else{
                     console.log('Creating bucket using temporary signature failed!');
                     console.log('status:' + serverback.statusCode);
                     console.log('\n');
              };
              buffers = Buffer.concat(buffers);
              if(buffers.length > 0){
                     console.log(buffers.toString());
              };
              console.log('\n');
       });
}).on('error',(err) => {
       console.log('Creating bucket using temporary signature failed!');
       console.log(err);
       console.log('\n');
});
if(content){
       req.write(content);
};
req.end();
```
#### 代码示例二：上传对象
本示例用于使用临时URL授权上传对象。
```
// 引入obs库
// 使用npm安装
const ObsClient = require("esdk-obs-nodejs");
// 使用源码安装
// var ObsClient = require('./lib/obs');
// 创建ObsClient实例
const obsClient = new ObsClient({
  // 推荐通过环境变量获取AKSK，这里也可以使用其他外部引入方式传入，如果使用硬编码可能会存在泄露风险
  // 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
  access_key_id: process.env.ACCESS_KEY_ID,
  secret_access_key: process.env.SECRET_ACCESS_KEY,
  // 【可选】如果使用临时AK/SK和SecurityToken访问OBS，同样建议您尽量避免使用硬编码，以降低信息泄露风险。您可以通过环境变量获取访问密钥AK/SK，也可以使用其他外部引入方式传入
  // security_token: process.env.SECURITY_TOKEN,
  // endpoint填写Bucket对应的Endpoint, 这里以华北-北京四为例，其他地区请按实际情况填写
  server: "https://obs.cn-north-4.myhuaweicloud.com",
});
function createSignedUrlSync() {
  // 指定HTTP方法类型, 这里以PUT为例
  const method = 'PUT';
  const params = {
    // 指定存储桶名称
    Bucket: "examplebucket",
    // 指定对象名，此处以 example/objectname 为例
    Key: "example/objectname",
    // 指定HTTP方法类型
    Method: method,
    // 指定签名URL的过期时间，这里以3600为例，单位为秒
    Expires: 3600,
    // 指定请求中携带的头域
    Headers: {
      "Content-Type": "text/plain",
    }
  };
  // 生成上传对象的带授权信息的URL
  const res = obsClient.createSignedUrlSync(params);
  console.log("SignedUrl: %s", res.SignedUrl);
  console.log("ActualSignedRequestHeaders: %v", res.ActualSignedRequestHeaders);
  let content  = 'Hello OBS';
  // 使用PUT请求上传对象
  var url = urlLib.parse(res.SignedUrl);
  var req = https.request({
    method: method,
    host: url.hostname,
    port: url.port,
    path: url.path,
    rejectUnauthorized: false,
    headers: res.ActualSignedRequestHeaders || {}
  });
  console.log('Creating object using url:' + res.SignedUrl);
  req.on('response', (serverback) => {
    var buffers = [];
    serverback.on('data', (data) => {
      buffers.push(data);
    }).on('end', () => {
      if (serverback.statusCode < 300) {
        console.log('Creating object using temporary signature succeed.');
      } else {
        console.log('Creating object using temporary signature failed!');
        console.log('status:' + serverback.statusCode);
        console.log('\n');
      };
      buffers = Buffer.concat(buffers);
      if (buffers.length > 0) {
        console.log(buffers.toString());
      };
      console.log('\n');
    });
  }).on('error', (err) => {
    console.log('Creating object using temporary signature failed!');
    console.log(err);
    console.log('\n');
  });
  if (content) {
    req.write(content);
  };
  req.end();
};
createSignedUrlSync();
```
#### 代码示例三：下载对象
本示例用于使用临时URL授权下载对象。
```
// 引入obs库
// 使用npm安装
const ObsClient = require("esdk-obs-nodejs");
// 使用源码安装
// var ObsClient = require('./lib/obs');
// 创建ObsClient实例
const obsClient = new ObsClient({
  // 推荐通过环境变量获取AKSK，这里也可以使用其他外部引入方式传入，如果使用硬编码可能会存在泄露风险
  // 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
  access_key_id: process.env.ACCESS_KEY_ID,
  secret_access_key: process.env.SECRET_ACCESS_KEY,
  // 【可选】如果使用临时AK/SK和SecurityToken访问OBS，同样建议您尽量避免使用硬编码，以降低信息泄露风险。您可以通过环境变量获取访问密钥AK/SK，也可以使用其他外部引入方式传入
  // security_token: process.env.SECURITY_TOKEN,
  // endpoint填写Bucket对应的Endpoint, 这里以华北-北京四为例，其他地区请按实际情况填写
  server: "https://obs.cn-north-4.myhuaweicloud.com",
});
function createSignedUrlSync() {
  // 指定HTTP方法类型, 这里以GET为例
  const method = 'GET';
  
  const params = {
    // 指定存储桶名称
    Bucket: "examplebucket",
    // 指定对象名，此处以 example/objectname 为例
    Key: "example/objectname",
    // 指定HTTP方法类型
    Method: method,
    // 指定签名URL的过期时间，这里以3600为例，单位为秒
    Expires: 3600,
  };
 
  // 使用GET请求下载对象
  var url = urlLib.parse(res.SignedUrl);
  var req = https.request({
    method: method,
    host: url.hostname,
    port: url.port,
    path: url.path,
    rejectUnauthorized: false,
    headers: res.ActualSignedRequestHeaders || {}
  });
  console.log('Creating object using url:' + res.SignedUrl);
  req.on('response', (serverback) => {
    var buffers = [];
    serverback.on('data', (data) => {
      buffers.push(data);
    }).on('end', () => {
      if (serverback.statusCode < 300) {
        console.log('Getting object using temporary signature succeed.');
      } else {
        console.log('Getting object using temporary signature failed!');
        console.log('status:' + serverback.statusCode);
        console.log('\n');
      };
      buffers = Buffer.concat(buffers);
      if (buffers.length > 0) {
        console.log(buffers.toString());
      };
      console.log('\n');
    });
  }).on('error', (err) => {
    console.log('Getting object using temporary signature failed!');
    console.log(err);
    console.log('\n');
  });
  req.end();
};
createSignedUrlSync();
```
#### 代码示例四：列举对象
本示例用于使用临时URL授权列举对象。
```
// 引入obs库
// 使用npm安装
const ObsClient = require("esdk-obs-nodejs");
// 使用源码安装
// var ObsClient = require('./lib/obs');
// 创建ObsClient实例
const obsClient = new ObsClient({
  // 推荐通过环境变量获取AKSK，这里也可以使用其他外部引入方式传入，如果使用硬编码可能会存在泄露风险
  // 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
  access_key_id: process.env.ACCESS_KEY_ID,
  secret_access_key: process.env.SECRET_ACCESS_KEY,
  // 【可选】如果使用临时AK/SK和SecurityToken访问OBS，同样建议您尽量避免使用硬编码，以降低信息泄露风险。您可以通过环境变量获取访问密钥AK/SK，也可以使用其他外部引入方式传入
  // security_token: process.env.SECURITY_TOKEN,
  // endpoint填写Bucket对应的Endpoint, 这里以华北-北京四为例，其他地区请按实际情况填写
  server: "https://obs.cn-north-4.myhuaweicloud.com",
});
function createSignedUrlSync() {
  // 指定HTTP方法类型, 这里以GET为例
  const method = 'GET';
  
  const params = {
    // 指定存储桶名称
    Bucket: "examplebucket",
    // 指定HTTP方法类型
    Method: method,
    // 指定签名URL的过期时间，这里以3600为例，单位为秒
    Expires: 3600,
  };
 
  // 使用GET请求获取对象列表
  var url = urlLib.parse(res.SignedUrl);
  var req = https.request({
    method: method,
    host: url.hostname,
    port: url.port,
    path: url.path,
    rejectUnauthorized: false,
    headers: res.ActualSignedRequestHeaders || {}
  });
  console.log('Listing object using url:' + res.SignedUrl);
  req.on('response', (serverback) => {
    var buffers = [];
    serverback.on('data', (data) => {
      buffers.push(data);
    }).on('end', () => {
      if (serverback.statusCode < 300) {
        console.log('Listing object using temporary signature succeed.');
      } else {
        console.log('Listing object using temporary signature failed!');
        console.log('status:' + serverback.statusCode);
        console.log('\n');
      };
      buffers = Buffer.concat(buffers);
      if (buffers.length > 0) {
        console.log(buffers.toString());
      };
      console.log('\n');
    });
  }).on('error', (err) => {
    console.log('Listing object using temporary signature failed!');
    console.log(err);
    console.log('\n');
  });
  req.end();
};
createSignedUrlSync();
```
#### 代码示例五：删除对象
本示例用于使用临时URL授权删除对象。
```
// 引入obs库
// 使用npm安装
const ObsClient = require("esdk-obs-nodejs");
// 使用源码安装
// var ObsClient = require('./lib/obs');
// 创建ObsClient实例
const obsClient = new ObsClient({
  // 推荐通过环境变量获取AKSK，这里也可以使用其他外部引入方式传入，如果使用硬编码可能会存在泄露风险
  // 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
  access_key_id: process.env.ACCESS_KEY_ID,
  secret_access_key: process.env.SECRET_ACCESS_KEY,
  // 【可选】如果使用临时AK/SK和SecurityToken访问OBS，同样建议您尽量避免使用硬编码，以降低信息泄露风险。您可以通过环境变量获取访问密钥AK/SK，也可以使用其他外部引入方式传入
  // security_token: process.env.SECURITY_TOKEN,
  // endpoint填写Bucket对应的Endpoint, 这里以华北-北京四为例，其他地区请按实际情况填写
  server: "https://obs.cn-north-4.myhuaweicloud.com",
});
function createSignedUrlSync() {
  // 指定HTTP方法类型, 这里以DELETE为例
  const method = 'DELETE';
  const params = {
    // 指定存储桶名称
    Bucket: "examplebucket",
    // 指定对象名，此处以 example/objectname 为例
    Key: "example/objectname",
    // 指定HTTP方法类型
    Method: method,
    // 指定签名URL的过期时间，这里以3600为例，单位为秒
    Expires: 3600,
  };
  // 使用DELETE请求删除对象
  var url = urlLib.parse(res.SignedUrl);
  var req = https.request({
    method: method,
    host: url.hostname,
    port: url.port,
    path: url.path,
    rejectUnauthorized: false,
    headers: res.ActualSignedRequestHeaders || {}
  });
  console.log('Deleting object using url:' + res.SignedUrl);
  req.on('response', (serverback) => {
    var buffers = [];
    serverback.on('data', (data) => {
      buffers.push(data);
    }).on('end', () => {
      if (serverback.statusCode < 300) {
        console.log('Deleting object using temporary signature succeed.');
      } else {
        console.log('Deleting object using temporary signature failed!');
        console.log('status:' + serverback.statusCode);
        console.log('\n');
      };
      buffers = Buffer.concat(buffers);
      if (buffers.length > 0) {
        console.log(buffers.toString());
      };
      console.log('\n');
    });
  }).on('error', (err) => {
    console.log('Deleting object using temporary signature failed!');
    console.log(err);
    console.log('\n');
  });
  req.end();
};
createSignedUrlSync();
```
