跳到主要内容

在URL中包含签名

除了在Header中包含Authorization字段来进行访问控制之外,用户还可以在URL中加入签名信息,这样用户就可以把该URL转给第三方实现授权访问。

在URL中实现签名,必须至少包含Signature,Expires,COSAccessKeyId三个参数。

  • Expires:UNIX时间(自UTC时间1970年1月1号开始的秒数),用于标识该URL的超时时间。如果COS接收到这个URL请求的时候晚于签名中包含的Expires参数时,则返回请求超时的错误码。例如:当前时间是1141559060,开发者希望创建一个20秒后自动失效的URL,则可以设置Expires时间为1141559080
  • COSAccessKeyId:即密钥对中的AccessKeyId,COS服务端将根据AccessKeyId找到AccessKeySecret,并计算最终的签名
  • Signature:表示签名信息,所有的COS支持的请求和各种Header参数,在URL中进行签名的算法和在Header中包含签名的算法基本一样。(在URL中包含签名的认证方式,当前只支持GetObject对象下载请求)
Signature = base64(hmac-sha256(AccessKeySecret,
VERB + "\n"
+ CONTENT-MD5 + "\n"
+ CONTENT-TYPE + "\n"
+ EXPIRES + "\n"
+ CanonicalizedCOSHeaders
+ CanonicalizedResource))

其中,与header中包含签名相比主要区别如下:

  1. 通过URL包含签名时,之前的Date参数换成Expires参数;
  2. 不支持同时在URL和Header中包含签名;
  3. 如果传入的Signature,Expires,COSAccessKeyId出现不止一次,以第一次为准;
  4. 请求先验证请求时间是否晚于Expires时间,然后再验证签名。

签名示例代码

假定用户需要生成mybucket桶中对象MyObject.txt的下载链接,截止有效期至1141559080,用户的密钥对为:

AccessKeyId = "YOUR_ACCESS_KEY_ID"
AccessKeySecret = "YOUR_ACCESS_KEY_SECRET"

那么,通过以上Signature计算方法,就可以计算出URL中的签名Signature:

import base64
import hmac
import hashlib

h = hmac.new("YOUR_ACCESS_KEY_SECRET",
"GET\n" + # HTTP-VERB
"\n" + # Content-Type
"\n" + # Content-MD5
"1141559080\n" + # Expires
"/mybucket/MyObject.txt", # CanonicalizedResource
hashlib.sha256)

print "Signature is " + base64.b64encode(h.digest())
# OUTPUT: Signature is r64OORFBNi0MbdNKLLEtpYbjiZwsu6DXVcvm7ByuyP0=

生成的私有桶下载URL链接为:

http://mybucket.cos-cn-suzhou.chinac.com/MyObject.txt? \
COSAccessKeyId=dcbf4036e50a4135aaab604f729a8115&\
Expires=1141559080&\
Signature=r64OORFBNi0MbdNKLLEtpYbjiZwsu6DXVcvm7ByuyP0=

最终的生成的私有桶下载URL链接为(参数和值需要urlencode):

http://mybucket.cos-cn-suzhou.chinac.com/MyObject.txt? \
COSAccessKeyId=dcbf4036e50a4135aaab604f729a8115&\
Expires=1141559080&\
Signature=r64OORFBNi0MbdNKLLEtpYbjiZwsu6DXVcvm7ByuyP0%3D

细节说明

  1. 使用在URL中签名的方式,会将你授权的数据在过期时间以内曝露在互联网上,请预先评估使用风险;
  2. 在URL中包含签名的认证方式,当前只支持GetObject对象下载请求;
  3. 在URL中添加签名时,Signature,Expires,COSAccessKeyId顺序可以交换,但是如果Signature,Expires,COSAccessKeyId缺少其中的一个或者多个,返回403 Forbidden。错误码:AccessDenied;
  4. 如果访问的当前时间晚于请求中设定的Expires时间,返回403 Forbidden。错误码:AccessDenied;
  5. 如果Expires时间格式错误,返回403 Forbidden。错误码:AccessDenied;
  6. 如果URL中包含参数Signature,Expires,COSAccessKeyId中的一个或者多个,并且Header中也包含签名消息,返回消息400 Bad Request。错误码:InvalidArgument;
  7. 生成签名字符串时,除Date被替换成Expires参数外,仍然包含Content-Type、Content-MD5等上节中定义的Header。(请求中虽然仍然有Date这个请求头,但不需要将Date加入签名字符串中)。