如何制作有效的hmac身份验证标头

时间:2018-12-06 15:01:51

标签: php laravel rest guzzle

我正在尝试使用combell api自动执行托管。我需要为API请求生成一个HMAC身份验证标头。我正在使用Guzzle。

带有标题的当前代码会产生此错误:

  

客户端错误:GET https://api.combell.com/v2/accounts导致401 Unauthorized响应:{“ error_code”:“ authorization_hmac_invalid”,“ error_text”:“ hmac无效。” }

我的控制器

class GuzzleController extends Controller
{
    protected $api_key;
    protected $api_secret;

    public function __construct()
    {
        $this->api_key = env('API_KEY');
        $this->api_secret = env('API_SECRET');
    }

    protected function hmacHandler() {
        $key = $this->api_key;
        $req_method = 'get';
        $path_query = 'https://api.combell.com/';
        $timestamp = time();
        $nonce = substr(md5(uniqid(mt_rand(), true)), 0, 8);
        $content = '';

        $valueToSign = $this->api_key
            . $req_method
            . urlencode($path_query)
            . $timestamp
            . $nonce
            . $content;

        $signedValue = hash_hmac('sha256', $valueToSign, $this->api_secret, true);

        $signature = base64_encode($signedValue);

        return sprintf('hmac %s:%s:%s:%s', $this->api_key, $signature, $nonce, $timestamp);
    }

    public function index() {

        dd($this->getTestData());
    }

    public function getTestData() {
        $client = new Client();
        $uri = 'https://api.combell.com/v2/accounts';
        $header = ['headers' => ['Authorization' => $this->hmacHandler()]];
        $res = $client->get($uri, $header);
        return json_decode($res->getBody()->getContents(), true);
    }
}

我不确定我的hmac功能是否不正确,或者我是否以错误的方式使用了Guzzle Authorization标头,是否有提示?

Combell API documentation

2 个答案:

答案 0 :(得分:1)

根据响应,“授权”标头很好(添加标头的语法看起来不错),但是该值不正确。

文档指出该路径必须是相对的。尝试替换

$path_query = 'https://api.combell.com/';

$path_query = '/v2/accounts';(或/accounts,文档尚不清楚)。

由于正文是空的,因此不需要该内容。

答案 1 :(得分:0)

我相信您的标题缺少信息。

signingString标识编码中使用的部分,并且还必须包含在标头中。

示例:

$date = gmdate("D, d M Y H:i:s") . " GMT";
$signingString = "Date: $date";
$signature = base64_encode(hash_hmac('sha1', $signingString, $secret, true));
$authorization = "hmac username=\"$user\", algorithm=\"hmac-sha1\", headers=\"Date\", signature=\"$signature\"";

$headers = ['Content-Type' => 'application/json',
        'Date' => $date,
        'Authorization' => $authorization,
        'Content-MD5' => $bodyHash ];

$options = [
   'headers' => $header,
   'json' => $body];
$response = $client->request('POST', $uri, $options);

在此示例中,' Date '字段在标头中传递,并带有一个值,该值与密钥和' Authorization (标头授权)标头标识要在解码过程中在“ 标头 ”子字段中抓取的字段。