• 什么是签名
  • 设计目的
  • 制作签名
    • AK/SK签名包含的内容
    • 制作AK/SK签名
    • token签名包含的内容
    • 制作token签名
    • 签名用法示例
    • CanonicalizedQiniuHeaders计算方式:
    • CanonicalizedResource计算方式:

    什么是签名

    签名是七牛服务器用来识别用户身份与权限的凭证,我们采用AK/SK(公钥/私钥)、token两种方式来对用户进行身份验证。

    设计目的

    • 对用户身份进行认证,使服务端获知该请求的发送者。
    • 防止身份假冒。
    • token分发,使用户可以在自己的应用服务器和app之间分发token,达到保护AK/SK的目的。

    制作签名

    AK/SK签名包含的内容

    参数 是否必须 说明
    method Http method,请求类别
    content-md5 Http content-md5,验证数据完整性
    content-type Http content-type,描述资源类型
    date 当前时间,要求为GTM格式,如Sun, 06 Nov 1994 08:49:37 GMT
    qiniu-headers 表示请求头中的一些自定义参数,以X-Qiniu-开头
    resource 目标资源(uri)

    制作AK/SK签名

    1.生成待签名的原始字符串

    1. strToSign = <method> + "\n"
    2. + <content-md5> + "\n"
    3. + <content-type> + "\n"
    4. + <date> + "\n"
    5. + <canonicalizedqiniuheaders>
    6. + <canonicalizedresource>

    2.使用SecretKey对上一步生成的strTosign计算HMAC-SHA1签名

    1. sign = hmac_sha1(strToSign "<SecretKey>")

    3.对sign进行URL安全的Base64编码

    1. encodedSign = urlsafe_base64_encode(sign)

    4.将AccessKeyencodedSign用英文符号:连接起来

    1. auth = "<AccessKey>:<encodedSign>"

    注意:签名字符串中的content-md5content-type为空那么相应的位置用空字符串来占位。Date参数与服务器时间的偏差不得超过15分钟,用户需要同步校准自己的时钟。频繁返回401状态码时请先检查Date相关的代码逻辑。

    token签名包含的内容

    参数 是否必须 说明
    method Http method,请求类别
    content-md5 Http content-md5,验证数据完整性
    content-type Http content-type,描述资源类型
    expires 过期时间,unix秒级时间戳
    qiniu-headers 表示请求头中的一些自定义参数,以X-Qiniu-开头
    resource 目标资源(uri)

    制作token签名

    1.构造tokenDescription

    1. tokenDescription =
    2. '{
    3. "resource": <Resource>,
    4. "expires": <Expires>
    5. "contentType": <ContentType>,
    6. "contentMD5": <ContentMD5>,
    7. "method": <Method>,
    8. "headers": <Headers>
    9. }'

    2.将tokenDescription进行URL安全的Base64编码,得到encodedTokenDescription

    1. encodedTokenDescription = urlsafe_base64_encode(tokenDescription)

    3.使用SecretKeyencodedTokenDescription计算HMAC-SHA1签名

    1. sign = hmac_sha1(encodedTokenDescription "<SecretKey>")

    4.对sign进行URL安全的Base64编码

    1. encodedSign = urlsafe_base64_encode(sign)

    5.将AccessKeyencodedSignencodedTokenDescription用英文符号:连接起来

    1. auth = "<AccessKey> + : + <encodedSign> + : + <encodedTokenDescription>"

    签名用法示例

    1. POST /v4/repos/<RepoName>
    2. Content-Type: application/json
    3. Authorization: Pandora <auth>
    4. {
    5. "region": <Region>,
    6. "metadata":{
    7. "key1":"value1"
    8. ...
    9. }
    10. }

    CanonicalizedQiniuHeaders计算方式:

    X-Qiniu-开头的header是七牛的服务自定义的头部,有其特殊意义,因此签名中也需要加进去所有的自定义头部,CanonicalizedQiniuHeaders的计算步骤如下:

    1.将所有以X-Qiniu-为前缀的HTTP请求头的名字转换成小写字母,例如X-Qiniu-pipeline-timeout: 20转换成x-qiniu-pipeline-timeout:20

    2.将上一步得到的所有的HTTP请求头按照名字的字典序进行升序排列;

    3.删除请求头和内容之间分隔符两端出现的空格;

    4.将每一个头和内容用\n分隔符分隔拼成最后的CanonicalizedQiniuHeaders

    • 注意:当不存在Qiniu headers的时候无需添加最后的换行符。

    CanonicalizedResource计算方式:

    用户希望访问pipeline的目标资源被称为CanonicalizedResource,计算步骤如下:

    1.将CanonicalizedResource置为空字符串(””);

    2.将请求的pipeline资源的uri放入CanonicalizedResource,例如/v2/repos/repox/exports/exportx

    3.如果请求的资源包含了子资源,那么将子资源按照字典序升序排列并以&为分隔符生成子资源,以?为分割符追加在CanonicalizedResource字符串的后面,例如/v2/repos/repos/repox?q1=v1&q2=v2