關於Kong閘道器客戶端請求的兩個小坑
阿新 • • 發佈:2019-02-12
服務端配置了Kong閘道器,要求請求頭攜帶必須的欄位,否則不能通過閘道器.
新增欄位很簡單,根據Kong的文件,不校驗body的請求頭必須欄位如下:
-H "Host: hmac.com" \ -H "Date: Thu, 22 Jun 2017 17:15:21 GMT" \ -H 'Authorization: hmac username="alice123", algorithm="hmac-sha256", headers="date request-line", signature="ujWCGHeec9Xd6UD2zlyxiNMCiXnDOWeVFMu5VeRUxtw="'
Host欄位的值替換為你真實的host值.
Date欄位有個小坑,一定是格林威治時間,不是東8區的時間!!!!!!!!!!!!!!
附上java程式碼獲取格林威治時間的程式碼:
DateFormat dateFormat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss 'GMT'", Locale.US); dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); String signDate = dateFormat.format(Calendar.getInstance().getTime());
PS:如果你使用東8區的北京時間,你會發現這個時間比你電腦右下角顯示的時間要慢8個小時整.這就對了.
Authorization欄位直接按照文件上的要求寫,username用閘道器配置的欄位.
簽名欄位計算如下:
signing_string="date: Thu, 22 Jun 2017 17:15:21 GMT\nGET /requests HTTP/1.1" digest=HMAC-SHA256(<signing_string>, "secret") base64_digest=base64(<digest>)
比較好理解,對獲取的時間和請求行進行簽名.
請求時間用之前的格林威治時間,請求行用抓包工具可以看到,其實就是[請求方式] + [請求地址] + [協議版本]
請求地址不要加host.
注意中間有一個\n,其實是'\n'一個換行符.
如果需要校驗body,請求頭還需要新增一個欄位:
-H "Digest: SHA-256=SBH7QEtqnYUpEcIhDbmStNd1MxtHg2+feBfWc1105MA=" \
欄位的值是對body進行計算,方法如下:
body="A small body"
digest=SHA-256(body)
base64_digest=base64(digest)
Digest: SHA-256=<base64_digest>
這個欄位需要加入簽名,最終的請求頭如下:
-H "Host: hmac.com" \
-H "Date: Thu, 22 Jun 2017 21:12:36 GMT" \
-H "Digest: SHA-256=SBH7QEtqnYUpEcIhDbmStNd1MxtHg2+feBfWc1105MA=" \
-H 'Authorization: hmac username="alice123", algorithm="hmac-sha256", headers="date request-line digest", signature="gaweQbATuaGmLrUr3HE0DzU1keWGCt3H96M28sSHTG8="' \
-d "A small body"
最終的的簽名signature計算的方法如下:
signing_string="date: Thu, 22 Jun 2017 17:15:21 GMT\nGET /requests HTTP/1.1\ndigest: SHA-256=[請求頭Disgest欄位的值]"
digest=HMAC-SHA256(<signing_string>, "secret")
base64_digest=base64(<digest>)
注意中間的兩個\n和disest欄位的加入方式.(官方文件上沒有寫,自己猜的,測試可以通過).
最終是對類似於這種格式的字串進行HMAC-SHA256和Base64計算:
date: Fri, 13 Apr 2018 09:12:53 GMT
POST /requests HTTP/1.1
digest: SHA-256=uy7reOKmOLfkc13qRMn5fWCV8Gy9MP0yjbS4sHvlXC0=
END