# GAPI服务
# 服务地址
https://g.sinacloud.com
# 签名规则
将所有x-sae-
开头的http header
(小写)按name排序后用冒号链接name和value,放在method、uri(包含query string,不要转义)后以换行符分隔拼接为签名原文字符串,再以Secretkey为密钥用hmac sha256计算哈希值(二进制),再经base64编码,前面加上"SAEV1_HMAC_SHA256 "
,得到本次请求的认证签名,即Authorization字段。
# 认证的请求头
请求头 | 说明 |
---|---|
x-sae-accesskey | 应用的Accesskey |
x-sae-timestamp | Unix时间戳 |
Authorization | 本次请求的认证签名 |
# 请求头示例
GET /log/http/2015-06-05/1-access.log HTTP/1.1
Host: g.sae.sina.com.cn
Accept: text/plain
x-sae-accesskey: 0xdeadbeef
x-sae-timestamp: 1433495016
Authorization: SAEV1_HMAC_SHA256 VQdy0s/D4aEn6QXAexr0onGmz+QObDwkWcZCCKcxMws=
# Python签名示例
import time
import base64
import hmac
import hashlib
TIMESTAMP = str(int(time.time()))
URI = '/log/http/2015-05-06/1-access.log?head/0/1'
# x-sae-开头的header的name需要是小写的
msgToSign = "\n".join(["GET", URI, "\n".join([(k + ":" + v) for k, v in sorted(HEADERS) if k.startswith('x-sae-')])])
signature = "SAEV1_HMAC_SHA256 " + base64.b64encode(hmac.new(SECRETKEY, msgToSign, hashlib.sha256).digest())
# PHP签名示例
<?php
namespace sinacloud\sae;
class Gapi
{
private $accessKey;
private $secretKey;
private $gapi = 'http://g.sinacloud.com';
public function __construct($accessKey, $secretKey)
{
$this->accessKey = $accessKey;
$this->secretKey = $secretKey;
}
/**
* 发送一个GET请求
* @param $uri
* @return bool|mixed
*/
public function get($uri)
{
if (!$uri) {
return false;
}
return $this->_curl($uri);
}
public function post($uri, $post_data = array())
{
if (!$uri) {
return false;
}
return $this->_curl($uri, $post_data, 'POST');
}
private function _cal_sign_and_set_header($ch, $uri, $method = 'GET')
{
$a = array();
$a[] = $method;
$a[] = $uri;
// $timeline unix timestamp
$timeline = time();
$b = array('x-sae-accesskey' => $this->accessKey, 'x-sae-timestamp' => $timeline);
ksort($b);
foreach ($b as $key => $value) {
$a[] = sprintf("%s:%s", $key, $value);
}
$str = implode("\n", $a);
$s = hash_hmac('sha256', $str, $this->secretKey, true);
$b64_s = base64_encode($s);
$headers = array();
$headers[] = sprintf('x-sae-accesskey:%s', $this->accessKey);
$headers[] = sprintf('x-sae-timestamp:%s', $timeline);
$headers[] = sprintf('Authorization: SAEV1_HMAC_SHA256 %s', $b64_s);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
return $headers;
}
private function _curl($uri, $post_data = array(), $method = 'GET')
{
$ch = curl_init();
$url = sprintf('%s%s', $this->gapi, $uri);
curl_setopt($ch, CURLOPT_URL, $url);
$this->_cal_sign_and_set_header($ch, $uri, $method);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if ($post_data) {
if (is_array($post_data)) {
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
} else {
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
}
}
$txt = curl_exec($ch);
$error = curl_errno($ch);
curl_close($ch);
if ($error) {
return false;
}
return $txt;
}
}
# 接口返回码说明
状态码 | 说明 |
---|---|
200 OK | 无错误 |
403 Forbidden | 认证失败 |
404 Not Found | 接口不存在等 |
405 Method Not Allowed | 不支持的http method |