1. 程式人生 > >關於Kong閘道器客戶端請求的兩個小坑

關於Kong閘道器客戶端請求的兩個小坑

服務端配置了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