
# 步骤1：构造规范化请求（CanonicalRequest）
使用AppId/AppSecret方式进行签名与认证，首先需要规范请求内容，然后再进行签名。第三方与Koodrive使用相同的请求规范，可以确保同一个HTTP请求的前后端得到相同的签名结果，从而完成身份校验。
```
CanonicalRequest =
HTTPRequestMethod + '\n' +    //http请求方法，全大写
  CanonicalURI + '\n' +         //规范化URI
  CanonicalQueryString + '\n' + //规范化查询字符串
  CanonicalHeaders + '\n' +     //规范化消息头
  SignedHeaders + '\n' +        //已签名消息头
  HashedRequestPayload
```
#### 构造HTTP请求方法（HTTPRequestMethod）
HTTP请求方法，如GET、PUT、POST等，以换行符结束。
#### 添加规范URI参数（CanonicalURI）
**释义**：
规范URI，即请求资源路径，是URI的绝对路径部分的URI编码。
**格式**：
根据RFC 3986标准化URI路径。
- 移除冗余和相对路径部分。
- 路径中每个部分必须为URI编码。
- 如果URI路径不以"/"结尾，则在尾部添加"/"。
 
#### 添加规范查询字符串（CanonicalQueryString）
**释义**：
查询字符串，即查询参数。如果没有查询参数，则为空字符串，即规范后的请求为空行。
**格式：**
规范查询字符串需要满足以下要求：
- 请勿对RFC 3986定义的任何非预留字符进行URI编码，这些字符包括：A-Z、a-z、0-9、-、_、.和\~。
- 使用%XY对所有非预留字符进行百分比编码，其中X和Y为十六进制字符（0-9和A-F）。例如，空格字符必须编码为%20，扩展UTF-8字符必须采用"%XY%ZA%BC"格式。
- 对于每个参数，追加"*URI编码的参数名称* =*URI编码的参数值* "。如果没有参数值，则以空字符串代替，但不能省略"="。例如以下含有两个参数，其中第二个参数parm2的值为空。
  parm1=value1\&parm2=
  
- 字符代码以升序顺序对参数名进行排序。例如，以大写字母F开头的参数名排在以小写字母b开头的参数名之前。
- 以排序后的第一个参数名开始，构造规范查询字符串。
 
#### 添加规范消息头（CanonicalHeaders）
**释义：**
规范消息头，即请求消息头列表。包括签名请求中的所有HTTP消息头列表。消息头必须包含X-Date，X-User-Id
**格式** **：**
CanonicalHeaders由多个请求消息头共同组成，**CanonicalHeadersEntry0 + CanonicalHeadersEntry1 + ...** ，其中每个请求消息头（CanonicalHeadersEntry）的格式为**Lowercase(HeaderName) + ':' + Trim(HeaderValue) + '\\n'**
**说明**：
- Lowercase(String)表示将所有字符转换为小写字母的函数。
- Trim(String)表示删除值前后的多余空格的函数。
- 最后一个请求消息头也会携带一个换行符。叠加规范中**CanonicalHeaders**自身携带的换行符，因此会出现一个空行。
- 消息头名称要保持唯一性，出现多个相同消息头名称时，无法完成认证。
 
#### 添加用于签名的消息头声明（SignedHeaders）
**释义**：
用于签名的请求消息头列表。通过添加此消息头，向Koodrive告知请求中哪些消息头是签名过程的一部分。X-Date、X-User-Id必须作为已签名的消息头。
**格式**：
SignedHeaders = Lowercase(HeaderName0) + ';' + Lowercase(HeaderName1) + ";" + ...
已签名的消息头需要满足以下要求：将已签名的消息头名称转换为小写形式，按照字符代码对消息头进行排序，并使用";"来分隔多个消息头。
**说明**：
Lowercase(String)表示将所有字符转换为小写字母。
#### 计算并添加基于请求正文中的body体的HASH值（HashRequestPayload）
**释义**：
使用请求的消息体生成哈希值。
伪代码如下：
```
HashRequestPayload = HexEncode(Hash(RequestPayload))
```
**说明**：
- Hash(String)表示生成消息摘要的函数，当前支持SHA-256算法。
- HexEncode(String)表示以小写字母形式返回摘要的Base-16编码的函数。输入的每一个字节都表示为两个十六进制字符。
 
