在使用七牛云時,開發者可能會遇到回調簽名驗證不一致的問題,這可能會導致應用邏輯上的錯誤。讓我們深入探討這一問題的原因以及如何解決。
問題背景
七牛云在進行回調時,會在請求的頭部包含一個 Authorization 字段,其格式為 QBox :。開發者需要使用同樣的算法來驗證簽名是否正確,以確保請求的合法性。
用戶提供了一段代碼,用于驗證七牛云的回調簽名,但發現計算出的簽名與七牛云提供的簽名不一致。具體代碼如下:
public function verifyCallbackSignature(Request $request): bool { $authstr = $request->header('Authorization'); if (empty($authstr) || strpos($authstr, "QBox ") !== 0) { supportLog::debug("簽名驗證失敗-頭部格式錯誤", [ 'sign_content' => 'qianmingshibai' ]); return false; } $auth = explode(":", substr($authstr, 5)); if (count($auth) !== 2 || $auth[0] !== env('QINIU_AK')) { supportLog::debug("簽名驗證失敗-AK不匹配", [ 'sign_content' => 'zhanghuAkshibai', 'auth_count' => count($auth), 'auth_ak' => $auth[0], ]); return false; } $data = $request->uri() . "n" . file_get_contents('php://input'); $re = $this->URLSafeBase64Encode(hash_hmac('sha1', $data, env('QINIU_SK'), true)) === $auth[1]; supportLog::debug("簽名驗證詳情", [ 'data' => $data, 'computed_sign' => $this->URLSafeBase64Encode(hash_hmac('sha1', $data, env('QINIU_SK'), true)), 'received_sign' => $auth[1], ]); return $re; }
用戶提到的問題是,計算出的 computed_sign 始終與七牛云傳來的簽名不一致,并且前端沒有發送請求體,導致后端獲取到的 php://input 為空。
解決方法
為了解決這個問題,修改后的代碼應該考慮以下幾點:
- 檢查請求體的完整性:確保從 php://input 讀取到的數據是正確的,如果沒有請求體,則應該處理這種情況。
- URI 的完整性:確保獲取的是完整的 URI,包括查詢字符串。
- 詳細的調試信息:增加調試信息的輸出,以便更容易定位問題。
下面是根據這些考慮點修改后的代碼:
public function verifyCallbackSignature(Request $request): bool { $authstr = $request->header('Authorization'); if (empty($authstr) || strpos($authstr, "QBox ") !== 0) { supportLog::debug("簽名驗證失敗-頭部格式錯誤", [ 'sign_content' => 'qianmingshibai', 'authstr' => $authstr, ]); return false; } $auth = explode(":", substr($authstr, 5)); if (count($auth) !== 2 || $auth[0] !== env('QINIU_AK')) { supportLog::debug("簽名驗證失敗-AK不匹配", [ 'sign_content' => 'zhanghuAkshibai', 'auth_count' => count($auth), 'auth_ak' => $auth[0], 'expected_ak' => env('QINIU_AK'), ]); return false; } // 獲取 URI 和請求體 $uri = $request->uri(); if (!empty($_SERVER['QUERY_STRING'])) { $uri .= '?' . $_SERVER['QUERY_STRING']; } $body = file_get_contents('php://input'); $data = $uri . "n" . $body; // 計算簽名 $computed_sign = $this->URLSafeBase64Encode(hash_hmac('sha1', $data, env('QINIU_SK'), true)); // 記錄調試信息 supportLog::debug("簽名驗證詳情", [ 'uri' => $uri, 'body' => $body, 'data' => $data, 'computed_sign' => $computed_sign, 'received_sign' => $auth[1], 'secret_key' => substr(env('QINIU_SK'), 0, 4) . '****', ]); return $computed_sign === $auth[1]; } public function URLSafeBase64Encode($data): string { return str_replace([' ', '/'], ['-', '_'], base64_encode($data)); }
這個修改后的版本增加了對 URI 查詢字符串的處理,并確保在計算簽名時考慮到了請求體的內容,即使請求體可能為空。同時,詳細的調試信息也增加了,以便于更快地診斷和解決問題。
通過這些調整,開發者應該能夠更好地處理七牛云的回調簽名驗證問題,確保應用的安全性和正確性。
? 版權聲明
文章版權歸作者所有,未經允許請勿轉載。
THE END