Laravel对接Hotelbeds API:Hex格式SHA256哈希鉴权解决方案
解决Hotelbeds API鉴权400 Bad Request问题
问题背景
在集成Hotelbeds API时,鉴权环节返回400 Bad Request错误。该API要求请求必须同时携带Api-key和X-Signature请求头,其中X-Signature的生成规则为:将Api密钥 + 共享密钥 + 当前秒级时间戳拼接成字符串后,生成Hex格式的SHA256哈希值。
官方提供的示例代码如下:
Bash示例
#!/bin/bash apiKey="yourApiKey" secret="yourSecret" curl -i \ -X GET \ -H 'Accept:application/json' \ -H 'Api-key:'$apiKey'' \ -H 'X-Signature:'$(echo -n ${apiKey}${secret}$(date +%s)|sha256sum|awk '{ print $1}')'' \ https://api.test.hotelbeds.com/hotel-api/1.0/status
Postman示例
//Begin UTC creation var utcDate = Math.floor(new Date().getTime() / 1000); //Begin Signature Assembly var publicKey = environment["Api-key"]; var privateKey = environment["secret"]; var assemble = (publicKey+privateKey+utcDate); //Begin SHA-256 Encryption hash = CryptoJS.SHA256(assemble).toString(); encryption = (hash.toString(CryptoJS.enc.Hex)); postman.setEnvironmentVariable("X-Signature", encryption);
我用Laravel编写的初始代码如下,但请求始终返回400错误:
$client = new \GuzzleHttp\Client(); $apiKey = "apiXXXXXXX"; $secret = "seceretXXXXX"; $assemble = $apiKey . $secret . Carbon::now()->timestamp; // $hash = Hash::make($assemble); $hash = base64_encode(hash('sha512', $assemble)); $headers = [ 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Api-key' => $apiKey, 'X-Signature' => $$hash, ]; $apiURL = 'https://api.test.hotelbeds.com/hotel-api/1.0/status'; $res = $client->request('GET', $apiURL, [ 'headers' => $headers, 'json' => [ "data" => [ "type" => "flight-offers-pricing", ] ], ]); $statusCode = $res->getStatusCode(); $responseBody = json_decode($res->getBody(), true); dd($responseBody);
错误原因分析
初始代码存在几个关键问题:
- 哈希算法不符合要求:使用了SHA512算法而非API要求的SHA256,还额外进行了base64编码,而API需要的是Hex格式的SHA256哈希
- 变量引用错误:
X-Signature的值写成了$$hash,多了一个美元符号,导致无法正确引用哈希变量 - 冗余请求参数:GET请求中携带了
json请求体,但/hotel-api/1.0/status接口不需要该参数,可能导致请求格式错误 - (非核心)时间戳获取:虽然
Carbon::now()->timestamp能获取秒级时间戳,但time()更直接,和官方示例逻辑一致
修正后的代码
$client = new \GuzzleHttp\Client(); $apiKey = "apixxxxxx"; $secret = "secxxxxxx"; // 按照规则生成X-Signature:SHA256(Api-Key + 共享密钥 + 秒级时间戳),默认返回Hex格式 $signature = hash("sha256", $apiKey . $secret . time()); $headers = [ 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Api-key' => $apiKey, 'X-Signature' => $signature, ]; $apiURL = 'https://api.test.hotelbeds.com/hotel-api/1.0/status'; $res = $client->request('GET', $apiURL, [ 'headers' => $headers, ]); $statusCode = $res->getStatusCode(); $responseBody = json_decode($res->getBody(), true); return $responseBody;
修正说明
- 使用
hash("sha256", $string)直接生成符合要求的Hex格式SHA256哈希,无需额外编码 - 修正变量引用错误,将
$$hash改为正确的$signature - 移除GET请求中不必要的
json参数,符合接口要求 - 用
time()获取秒级时间戳,和官方示例逻辑保持一致
内容的提问来源于stack exchange,提问作者user17171534
相关产品推荐
相关产品推荐

