## API签名
每一个合法的用户应该具有两个重要的信息`token_id`和`secret_key`。用户使用这两个信息,再加上一些必要的参数构造出`signature`。然后组合成最终的请求,使用 HTTP GET 方法提供给服务端,服务端就可以进行合法验证,并且把 结果返回给用户。
在一般的情况下,客户请求的时候必须提供八个信息
- `token_id`, 颁发给用户的`token_id`,每一个用户的`token_id`都是不一样的。
- `signature`, 用户使用签名算法计算出来的值。
- `expired`, 生成的URL超时时间。
- `img_type`, 请求的图片类型。
- `img_opt`, 这是图片转换服务所需要的参数,具体如何构造,请参考后面的章节。
- `timestamp`, 用户请求的当前UTC UNIX时间戳。一共十位数,例如:1453022611
- `rec_inv`,一个经过BASE64的JSON数据,请参考后面的描述。
- `version`,`1.0` 当前固定值
| 参数 |类型 | 是否必须 | 取值范围| 默认值 | 描述 |
| -- | -- | -- | -- | -- | -- |
| token_id | string | 是 | | | |
| signature | string | 是 | | | |
| expired | int | 是 | [3600 - 9600] | | |
| img_type | string | 是 | | | |
| img_opt | string | 否 | | | |
| timestamp | int | 是 | | | |
| rec_inv | string | 否 | | | |
| version | string | 是 | | 1.0 | |
签名过程要经过几步。
1. 将七个参数`token_id`,`expired`,`img_type`,`img_opt`,`timestamp`,`version`,`rec_inv`(除了`Signature`)按字典序排序。
2. 每一个参数和相应的值使用&连接起来,组成一个字符串`raw_string`,参数和值之间使用`=`号连接。
3. 使用HMAC-SHA1算法,将得到的字符串`raw_string`以`token_key`为密码进行加密。得到一个160位(20个字节)的数据。
4. 将HMAC-SHA1得到的20个字节的数据进行BASE64编码得到一个28个字节的字符串。
5. 得到了最终的signature的值。
签名之后构造请求字符串。这个时候将上面包括`signature`的八个参数使用`&`链接起来。
注意: 对每个请求参数的名称和值分别进行URL编码(仅支持UTF-8字符集)
> - 对于字符 A-Z、a-z、0-9以及字符“-”、“_”、“.”、“~”不编码;
> - 对于其他字符编码成“%XY”的格式,其中XY是字符对应ASCII码的16进制表示。比如英文的双引号(”)对应的编码就是%22;
> - 对于扩展的UTF-8字符,编码成“%XY%ZA…”的格式;
> - 需要说明的是英文空格( )要被编码是%20,而不是加号(+)。
> - 注意:一般支持URL编码的库(比如Java中的java.net.URLEncoder)都是按照“application/x-www-form-urlencoded”的MIME类型的规则进行编码的。实现时可以直接使用这类方式进行编码,把编码后的字符串中加号(+)替换成%20、星号(*)替换成%2A、%7E替换回波浪号(~),即可得到上述规则描述的编码字符串。
### 示例
假如我们参数有以下值
| 参数 | 值 |
| -- | -- |
| token_id | 123456789ABCDEF0 |
| expired | 3600 |
| img_type | 4d |
| img_opt | eyJoIjoyNTAsInciOjI1MH0K |
| timestamp | 1453022611 |
| rec_inv | eyJldCI6MCwic3QiOjE0NjE0NTcyMDB9Cg== |
| version | 1.0 |
其中`img_opt`的值是由如下的JSON经过Base64转换得到的。
```json
{"h":250,"w":250}
```
假设用户的`token_key`值是`0123456789ABCDEF`
-----
第一步:将参数和值使用`=`号连接在一起,并且按字典顺序排序,然后使用`&`符号将所有键值对连接起来形成一个字符串,得到如下的字符串
```
expired=3600&img_opt=bnVsbAo%3D&img_type=4d_2_2&rec_inv=eyJldCI6MCwic3QiOjE0NjE0NTcyMDB9Cg%3D%3D&signature=J2UHusKaEajZ6nyGIat6peeGPdA%3D×tamp=1461507293&token_id=123456789ABCDEF0&version=1.0
```
第二步:将得到的字符串使用HMAC-SHA1算法,密码为`token_key`进行加密。将会得到160位,20个字节的数据,然后将这20个字节进行BASE64编码得到一个28位的字符串,如下所示。
```
tfcJ99Y9FlHwA2Wt7uA9DMx5V3Y=
```
这个值就是`Signature`值。
第三步:`Signature`值计算完了之后,对每个请求参数的名称和值分别进行URL编码,然后使用`&`连接起来就得到最终请求参数,如下所示:
```
expired=3600&img_opt=eyJoIjoyNTAsInciOjI1MH0%3D&img_type=4d&signature=tfcJ99Y9FlHwA2Wt7uA9DMx5V3Y%3D×tamp=1453022611&token_id=123456789ABCDEF0&version=1.0
```
第四步:将所得到的参数添加到域名之后,就可以得到最新的更新了:
例如用户的请求地址是`http://update.runimg.com:5291/index.php/lastupdate`。因此最后生成的请求是
```
http://update.runimg.com:5291/index.php/lastupdate?rec_inv=eyJldCI6MCwic3QiOjE0NjE0NTcyMDB9Cg%3D%3D&signature=J2UHusKaEajZ6nyGIat6peeGPdA%3D×tamp=1461507293&token_id=123456789ABCDEF0&version=1.0
```
使用HTTP的GET请求,就可以得到最新的图片URL了。
