代码之家  ›  专栏  ›  技术社区  ›  Dax

如何生成有效的HMAC身份验证头

  •  1
  • Dax  · 技术社区  · 6 年前

    我正在尝试使用Combell API来自动进行托管。我需要为API请求生成一个HMAC身份验证头。我在用大嘴巴。

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

    客户端错误:get https://api.combell.com/v2/accounts 导致A 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授权头,有什么提示吗?

    Combell API documentation

    2 回复  |  直到 6 年前
        1
  •  1
  •   piscator    6 年前

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

    文档声明路径必须是相对路径。尝试替换

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

    具有

    $path_query = '/v2/accounts'; (或) /accounts ,医生不清楚)。

    内容不应该是必需的,因为主体是空的。

        2
  •  0
  •   Brian    6 年前

    我相信你的头条缺少信息。

    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);
    

    在本例中,是 日期 '字段在头中传递一个值,用于带机密和' 授权 '标题标识要在' 报头 '子字段作为解码的一部分。