如何解決七牛云回調簽名驗證不一致的問題?

在使用七牛云時,開發者可能會遇到回調簽名驗證不一致的問題,這可能會導致應用邏輯上的錯誤。讓我們深入探討這一問題的原因以及如何解決。

問題背景

七牛云在進行回調時,會在請求的頭部包含一個 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 為空。

解決方法

為了解決這個問題,修改后的代碼應該考慮以下幾點:

  1. 檢查請求體的完整性:確保從 php://input 讀取到的數據是正確的,如果沒有請求體,則應該處理這種情況。
  2. URI 的完整性:確保獲取的是完整的 URI,包括查詢字符串
  3. 詳細的調試信息:增加調試信息的輸出,以便更容易定位問題。

下面是根據這些考慮點修改后的代碼:

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
喜歡就支持一下吧
點贊8 分享