阿里云oss

具体步骤如下:

  1. 客户端向应用服务器发出上传文件到OSS的请求。
  2. 应用服务器向STS服务器请求一次,获取临时凭证。
  3. 应用服务器回复客户端,将临时凭证返回给客户端。
  4. 客户端获取上传到OSS的授权(STS的AccessKey以及Token),调用OSS提供的移动端SDK上传。
  5. 客户端成功上传数据到OSS。如果没有设置回调,则流程结束。如果设置了回调功能,OSS会调用相关的接口。

1、oss访问域名

通过外网访问OSS服务 

<Schema>://<Bucket>.<外网Endpoint>/<Object> 
  • Schema:HTTP或者为HTTPS
  • Bucket:OSS存储空间
  • Endpoint:Bucket所在数据中心的访问域名,您需要填写外网Endpoint
  • Object:上传到OSS上的文件

示例:如您的Region为华东1(oss-cn-hangzhou),Bucket名称为abc,Object名称为myfile/aaa.txt,那么您的外网访问地址为:

abc.oss-cn-hangzhou.aliyuncs.com/myfile/aaa.txt

2、访问授权获取

用户可以在HTTP请求中增加 Authorization 的Header来包含签名(Signature)信息,表明这个消息已被授权。

 

Authorization字段计算的方法

 
Authorization = "OSS " + AccessKeyId + ":" + Signature
Signature = base64(hmac-sha1(AccessKeySecret,
            VERB + "\n"
            + Content-MD5 + "\n" 
            + Content-Type + "\n" 
            + Date + "\n" 
            + CanonicalizedOSSHeaders
            + CanonicalizedResource))
  • AccessKeySecret 表示签名所需的密钥。
  • VERB表示HTTP 请求的Method,主要有PUT、GET、POST、HEAD、DELETE等。
  • \n 表示换行符。
  • Content-MD5 表示请求内容数据的MD5值,对消息内容(不包括头部)计算MD5值获得128比特位数字,对该数字进行base64编码而得到。该请求头可用于消息合法性的检查(消息内容是否与发送时一致),如”eB5eJF1ptWaXm4bijSPyxw==”,也可以为空。详情请参见RFC2616 Content-MD5
  • Content-Type 表示请求内容的类型,如”application/octet-stream”,也可以为空。
  • Date 表示此次操作的时间,且必须为GMT格式,如”Sun, 22 Nov 2015 08:16:38 GMT”。
  • CanonicalizedOSSHeaders 表示以 x-oss- 为前缀的HTTP Header的字典序排列。
  • CanonicalizedResource 表示用户想要访问的OSS资源。

其中,Date和CanonicalizedResource不能为空;如果请求中的Date时间和OSS服务器的时间差15分钟以上,OSS服务器将拒绝该服务,并返回HTTP 403错误。

 javascript实现:

 

构建CanonicalizedOSSHeaders的方法

所有以 x-oss- 为前缀的HTTP Header被称为CanonicalizedOSSHeaders。它的构建方法如下:

  1. 将所有以 x-oss- 为前缀的HTTP请求头的名字转换成小写 。如X-OSS-Meta-Name: TaoBao转换成x-oss-meta-name: TaoBao
  2. 如果请求是以STS获得的AccessKeyId和AccessKeySecret发送时,还需要将获得的security-token值以 x-oss-security-token:security-token 的形式加入到签名字符串中。
  3. 将上一步得到的所有HTTP请求头按照名字的字典序进行升序排列。
  4. 删除请求头和内容之间分隔符两端出现的任何空格。如x-oss-meta-name: TaoBao转换成:x-oss-meta-name:TaoBao
  5. 将每一个头和内容用 \n 分隔符分隔拼成最后的CanonicalizedOSSHeaders。
 说明
  • CanonicalizedOSSHeaders可以为空,无需添加最后的 \n
  • 如果只有一个,则如 x-oss-meta-a\n,注意最后的\n
  • 如果有多个,则如 x-oss-meta-a:a\nx-oss-meta-b:b\nx-oss-meta-c:c\n,注意最后的\n

构建CanonicalizedResource的方法

用户发送请求中想访问的OSS目标资源被称为CanonicalizedResource。它的构建方法如下:

  1. 将CanonicalizedResource置成空字符串 ""
  2. 放入要访问的OSS资源 /BucketName/ObjectName(如果没有ObjectName则CanonicalizedResource为”/BucketName/“,如果同时也没有BucketName则为“/”)
  3. 如果请求的资源包括子资源(SubResource) ,那么将所有的子资源按照字典序,从小到大排列并以 & 为分隔符生成子资源字符串。在CanonicalizedResource字符串尾添加 和子资源字符串。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&uploadId=UploadId
  4. 如果用户请求在指定了查询字符串(QueryString,也叫Http Request Parameters),那么将这些查询字符串及其请求值按照字典序,从小到大排列,以 & 为分隔符,按参数添加到CanonicalizedResource中,如:/BucketName/ObjectName?acl&response-content-type=ContentType&uploadId=UploadId

计算签名头规则

  • 签名的字符串必须为 UTF-8 格式。含有中文字符的签名字符串必须先进行 UTF-8 编码,再与 AccessKeySecret计算最终签名。
  • 签名的方法用RFC 2104中定义的HMAC-SHA1方法,其中Key为 AccessKeySecret` 。
  • Content-Type 和 Content-MD5 在请求中不是必须的,但是如果请求需要签名验证,空值的话以换行符 \n 代替。
  • 在所有非HTTP标准定义的header中,只有以 x-oss- 开头的header,需要加入签名字符串;其他非HTTP标准header将被OSS忽略(如上例中的x-oss-magic是需要加入签名字符串的)。
  • 以 x-oss- 开头的header在签名验证前需要符合以下规范:
    • header的名字需要变成小写。
    • header按字典序自小到大排序。
    • 分割header name和value的冒号前后不能有空格。
    • 每个Header之后都有一个换行符“\n”,如果没有Header,CanonicalizedOSSHeaders就设置为空。

1、Date:

dateFormat(new Date(), 'UTC:ddd, dd mmm yyyy HH:MM:ss \'GMT\''),

 

2、Content-MD5

headers['Content-Md5'] = crypto
      .createHash('md5')
      .update(new Buffer(params.content, 'utf8'))
      .digest('base64');

  

3、CanonicalizedOSSHeaders stsToken

headers['x-oss-security-token'] = stsToken;

  

4、CanonicalizedResource

/BucketName/ObjectName

  计算resource

proto._getResource = function _getResource(params) {
  let resource = '/';
  if (params.bucket) resource += `${params.bucket}/`;
  if (params.object) resource += params.object;

  return resource;
};

  

5、创建签名字符串

exports.buildCanonicalString = function canonicalString(method, resourcePath, request, expires) {
  request = request || {};
  const headers = request.headers || {};
  const OSS_PREFIX = 'x-oss-';
  const ossHeaders = [];
  const headersToSign = {};

  let signContent = [
    method.toUpperCase(),
    headers['Content-Md5'] || '',
    headers['Content-Type'] || headers['Content-Type'.toLowerCase()],
    expires || headers['x-oss-date']
  ];

  Object.keys(headers).forEach((key) => {
    const lowerKey = key.toLowerCase();
    if (lowerKey.indexOf(OSS_PREFIX) === 0) {
      headersToSign[lowerKey] = String(headers[key]).trim();
    }
  });

  Object.keys(headersToSign).sort().forEach((key) => {
    ossHeaders.push(`${key}:${headersToSign[key]}`);
  });

  signContent = signContent.concat(ossHeaders);

  signContent.push(this.buildCanonicalizedResource(resourcePath, request.parameters));

  return signContent.join('\n');
};

  计算签名

/**
 * @param {String} accessKeySecret
 * @param {String} canonicalString
 */
exports.computeSignature = function computeSignature(accessKeySecret, canonicalString) {
  const signature = crypto.createHmac('sha1', accessKeySecret);
  return signature.update(new Buffer(canonicalString, 'utf8')).digest('base64');
};

  计算authoraion

/**
 * @param {String} accessKeyId
 * @param {String} accessKeySecret
 * @param {String} canonicalString
 */
exports.authorization = function authorization(accessKeyId, accessKeySecret, canonicalString) {
  return `OSS ${accessKeyId}:${this.computeSignature(accessKeySecret, canonicalString)}`;
};

  

 
posted @ 2019-01-09 21:43  tutu_python  阅读(618)  评论(0)    收藏  举报