Lidemy HTTP Challenge 紀錄

圖片來源: https://www.ionos.com/

API文件


第 0 關 - 說明

挑戰連結

第0關主要在說明一些遊戲規則,但有一個重點詞 query string ,在串接 API 時時常會使用到的一個技巧,後面也會使用到。

第 1 關 - GET / Query String

挑戰連結

這關較為單純,只需要在瀏覽器網址列的 query string 後帶上自己的名字傳入即可。

1
https://lidemy-http-challenge.herokuapp.com/lv1?token={GOGOGO}&name='dylan'

Postman

JavaScript

Postman右側的code點進去可以選擇JavaScript原始碼

1
2
3
4
5
6
7
8
9
10
11
12
var data = null;
var xhr = new XMLHttpRequest();

xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});

xhr.open("GET", "https://lidemy-http-challenge.herokuapp.com/lv1?token={GOGOGO}&name=%27dylan%27");
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(data);

第 2 關 - GET / Query String

挑戰連結

和第一關一樣用 query string 傳送參數即可。

1
https://lidemy-http-challenge.herokuapp.com/lv2?token={HellOWOrld}&id=56

Postman

JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
var data = null;
var xhr = new XMLHttpRequest();

xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});

xhr.open("GET", "https://lidemy-http-challenge.herokuapp.com/lv2?token={HellOWOrld}&id=56");
xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded");
xhr.send(data)

第 3 關 - POST

挑戰連結

這關需要使用 POST 來新增書籍資料。

需求

  • 新增書籍的 API 網址為 https://lidemy-http-challenge.herokuapp.com/api
  • 資料的 content typeapplication/x-www-form-urlencoded 格式,這部分需要在撰寫程式碼時加入 request header 當中。

Postman

JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var data = "name=《大腦喜歡這樣學》&ISBN=9789863594475";

var xhr = new XMLHttpRequest();

xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});

xhr.open("POST", "https://lidemy-http-challenge.herokuapp.com/api/books");
xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded"); /*!!*/

xhr.send(data);

做完第一步伺服器回傳 {"message":"新增成功","id":"1989"},接著再把 id 以 query string傳給伺服器就過關了。

1
https://lidemy-http-challenge.herokuapp.com/lv3?token={5566NO1}&id=1989

第 4 關 - Query String過濾資料

挑戰連結

需求

  • API網址為 https://lidemy-http-challenge.herokuapp.com/api/books
  • 查詢書籍的方式為 /books?q=書名
  • 方法為 GET

Postman

JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});

xhr.open("GET", "https://lidemy-http-challenge.herokuapp.com/api/books?q=%E4%B8%96%E7%95%8C");

xhr.send(data);

得到 id 後再透過網址列傳送給伺服器即可

1
https://lidemy-http-challenge.herokuapp.com/lv4?token={LEarnHOWtoLeArn}&id=79

第 5 關 - DELETE

挑戰連結

這關需要刪除一本書籍資料,此資料的 id 為 23。

需求

  • 刪除的API網址為 https://lidemy-http-challenge.herokuapp.com/api
  • 刪除書籍的方式為 /books/:id
  • 方法為 DELETE

Postman

JavaScript

1
2
3
4
5
6
7
8
9
10
11
var data = null
var xhr = new XMLHttpRequest();

xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});

xhr.open("DELETE", "https://lidemy-http-challenge.herokuapp.com/api/books/23");
xhr.send(data)

第 6 關 - 登入驗證

挑戰連結
此關開始使用新的API (需驗證)

關卡敘述

我終於知道上次哪裡怪怪的了!

照理來說要進入系統應該要先登入才對,怎麼沒有登入就可以新增刪除…
這太奇怪了,我已經回報給那邊的工程師了

這邊是帳號密碼,你先登入試試看吧,可以呼叫一個 /me 的 endpoint,裡面會給你一個 email。
把 email 放在 query string 上面帶過來,我看看是不是對的。

帳號:admin
密碼:admin123

需求

以下 endpoint 都必須經由 HTTP 驗證,驗證方法為傳入 Authorization 的 Header

首先你必須準備好一組字串,內容為 base64(username:password)
舉例來說,如果 username 是 aaa,password 是 123 的話,就會是字串 aaa:123 拿去做 base64 編碼之後得到的結果
再把這個結果放到 Header 去,最後變成: Authorization: Basic YWFhOjEyMw==
只要帶上這個 Header 就可以驗證身份囉!

(提示:可查詢關鍵字 http basic authorization

搜索關鍵字 http basic authorization

base64加密

為了使用者的安全,通常在進行密碼傳遞時會進行一層加密,http basic authorization是其中一種最簡單的方式,作法是將密碼轉譯為 BASE64 格式,再透過明碼方式傳送,雖然相對容易,但安全性比較低。

我們需要將文件此題所提供的帳號(admin)密碼(admin123)以admin:admin123格式丟入BASE64編碼器中,完成編碼後得到YWRtaW46YWRtaW4xMjM=。 最後組成完整的http basic authorization則會變成Authorization: Basic YWRtaW46YWRtaW4xMjM=

Postman

  • API路徑 https://lidemy-http-challenge.herokuapp.com/api/v2/me
  • 夾帶 request header Authorization: Basic YWRtaW46YWRtaW4xMjM=
  • 方法 GET

JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
13
var data = null;
var xhr = new XMLHttpRequest();

xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});

xhr.open("GET", "https://lidemy-http-challenge.herokuapp.com/api/v2/me");
xhr.setRequestHeader("Authorization", "Basic YWRtaW46YWRtaW4xMjM=");

xhr.send(data);

將回傳的 E-mail 放在 query string 上面回傳

1
https://lidemy-http-challenge.herokuapp.com/lv6?token={CHICKENCUTLET}&email=lib@lidemy.com

第 7 關 - DELETE

挑戰連結

需求

  • 要刪除的書 ID 為 89
  • 方法為 DELETE
  • API路徑 https://lidemy-http-challenge.herokuapp.com/api/v2
  • endpoint 為 /books/:id
  • 需要包含 http basic authorization 的驗證 request header

Postman

JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
var data = null;
var xhr = new XMLHttpRequest();

xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});

xhr.open("DELETE", "https://lidemy-http-challenge.herokuapp.com/api/v2/books/89");
xhr.setRequestHeader("Authorization", "Basic YWRtaW46YWRtaW4xMjM=");
xhr.send(data);

第 8 關 - PATCH (PUT)

挑戰連結

關卡敘述

我昨天在整理書籍的時候發現有一本書的 ISBN 編號跟系統內的對不上,仔細看了一下發現我當時輸入系統時 key 錯了。
哎呀,人老了就是這樣,老是會看錯。

那本書的名字裡面有個「我」,作者的名字是四個字,key 錯的 ISBN 最後一碼為 7,只要把最後一碼改成 3 就行了。
對了!記得要用新的系統喔,舊的已經完全廢棄不用了。

需求

  • GET方法透過 query string 查詢該書籍
  • PATCH方法修改書籍的 ISBN 資訊 (一樣須帶驗證)

Postman


JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
var data = null;
var xhr = new XMLHttpRequest();

xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});

xhr.open("GET", "https://lidemy-http-challenge.herokuapp.com/api/v2/books?q=我");
xhr.setRequestHeader("Authorization", "Basic YWRtaW46YWRtaW4xMjM=");
xhr.send(data);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var data = "name=日日好日:茶道教我的幸福15味【電影書腰版】&ISBN=9981835423";

var xhr = new XMLHttpRequest();

xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});

xhr.open("PATCH", "https://lidemy-http-challenge.herokuapp.com/api/v2/books/72");
xhr.setRequestHeader("Authorization", "Basic YWRtaW46YWRtaW4xMjM=");
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

xhr.send(data);

第 9 關 - User-agent定義瀏覽器

挑戰連結

關卡敘述

API 文件裡面有個獲取系統資訊的 endpoint 你記得嗎?
工程師跟我說這個網址不太一樣,用一般的方法是沒辦法成功拿到回傳值的。

想要存取的話要符合兩個條件:

  1. 帶上一個 X-Library-Number 的 header,我們圖書館的編號是 20
  2. 伺服器會用 user agent 檢查是否是從 IE6 送出的 Request,不是的話會擋掉

順利拿到系統資訊之後應該會有個叫做 version 的欄位,把裡面的值放在 query string 給我吧。

需求

  • 補上對應的 header ,包含登入驗證
  • 偽造IE6的 ` request header

Postman

JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var data = null;
var xhr = new XMLHttpRequest();

xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});

xhr.open("GET", "https://lidemy-http-challenge.herokuapp.com/api/v2/sys_info");
xhr.setRequestHeader("Authorization", "Basic YWRtaW46YWRtaW4xMjM=");
xhr.setRequestHeader("X-Library-Number", "20");
xhr.setRequestHeader("User-Agent", "Mozilla/5.0 (Windows; U; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)");

xhr.send(data);

query string 回傳剛剛得到的 version資訊

1
https://lidemy-http-challenge.herokuapp.com/lv9?token={NeuN}&version=1A4938Jl7

第 10 關 - 邏輯遊戲

挑戰連結

關卡敘述

出題者會出一個四位數不重複的數字,例如說 9487。
你如果猜 9876,我會跟你說 1A2B,1A 代表 9 位置對數字也對,2B 代表 8 跟 7 你猜對了但位置錯了。

開始吧,把你要猜的數字放在 query string 用 num 當作 key 傳給我。

需求

這是一個邏輯遊戲,就試吧

  • 如果1個數字對且位置也對就會顯示 1A,兩個的話則顯示 2A,依此類推
  • 若玩家其中一個數字猜對但是位置錯,則會顯示 1B,兩個的話則顯示 2B,依此類推

解答

1
https://lidemy-http-challenge.herokuapp.com/lv10?token={duZDsG3tvoA}&num=9613

第 11 關 - Origin 跨域限制

挑戰連結

關卡敘述

嘿!很開心看到你願意回來繼續幫忙,這次我們接到一個新的任務,要跟在菲律賓的一個中文圖書館資訊系統做串連
這邊是他們的 API 文件,你之後一定會用到:https://gist.github.com/aszx87410/0b0d3cabf32c4e44084fadf5180d0cf4。

現在就讓我們先跟他們打個招呼吧,只是我記得他們的 API 好像會限制一些東西就是了…

需求

  • 從 API 文件參考基本 API 路徑為 https://lidemy-http-challenge.herokuapp.com/api/v3
  • 打招呼的 endpoint 為 /hello
  • request header 內偽造 origin ( 此API有CROS跨域限制,必須來自 lidemy.com 才可存取 )
  • 方法為 GET

Postman

JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
var data = null;
var xhr = new XMLHttpRequest();

xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});

xhr.open("GET", "https://lidemy-http-challenge.herokuapp.com/api/v3/hello");
xhr.setRequestHeader("Origin", "lidemy.com");
xhr.send(data);

第 12 關 - 使用開發者工具Network觀察回傳的response header資訊

挑戰連結

關卡敘述

使用 API 文件提供的方法,獲得藏在其中的 token

需求

使用瀏覽器開發者工具的 Network分頁觀察 request ,並於網址列中輸入網址,訪問 API

過程

當訪問該 API 後,我們被轉址到其他地方了,順序如下:

  • deliver_token > stopover > deliver_token_result

可以透過 Network 分頁觀察 stopover ,發現 header 內夾帶下一關的 token X-Lv13-Token: {qspyz}


第 13 關 - Proxy代理伺服器

挑戰連結

關卡敘述

太好了!自從你上次把運送用的 token 拿回來以後,我們就密切地與菲律賓在交換書籍
可是最近碰到了一些小問題,不知道為什麼有時候會傳送失敗
我跟他們反映過後,他們叫我們自己去拿 log 來看,你可以幫我去看看嗎?
從系統日誌裡面應該可以找到一些端倪。

解題

如果直接用 GET 方法,會得到這段伺服器回傳提示:

此 request 不是來自菲律賓,禁止存取系統資訊。

網址後帶入 &hint=13 看看提示

你有聽過代理伺服器 proxy 嗎?

1. 我們可在 chrome 的設定頁面中搜尋 proxy ,即可開啟設定視窗

2. 上網搜尋 proxy 站點

菲律賓proxy

勾選協議是 HTTP 按下搜尋,可以挑選一個速度快的服務。要注意不是每個 proxy 都能正常使用,可能需要多嘗試幾次。

接著在網址列輸入以下,訪問該 API

1
https://lidemy-http-challenge.herokuapp.com/api/v3/logs

3. 成功

成功可以看到以下畫面,得知下一關 token{SEOisHard}

1
2
3
[
{ logType: 'token', value: '{SEOisHard}' }
]

第 14 關 - User-agent定義搜尋引擎

挑戰連結

關卡敘述

跟那邊的溝通差不多都搞定了,真是太謝謝你了,關於這方面沒什麼問題了!
不過我老大昨天給了我一個任務,他希望我去研究那邊的首頁內容到底是怎麼做的
為什麼用 Google 一搜尋關鍵字就可以排在第一頁,真是太不合理了
他們的網站明明就什麼都沒有,怎麼會排在那麼前面?
難道說他們偷偷動了一些手腳?讓 Google 搜尋引擎看到的內容跟我們看到的不一樣?
算了,還是不要瞎猜好了,你幫我們研究一下吧!

解題

網址後帶入 &hint=14 看看提示

伺服器是怎麼辨識是不是 Google 搜尋引擎的?仔細想想之前我們怎麼偽裝自己是 IE6 的。

第九關我們曾經使用 ` 這個 request header 來偽裝瀏覽器,這題也需要朝這個方向著手。

Postman

JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
var data = null;
var xhr = new XMLHttpRequest();

xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});

xhr.open("GET", "https://lidemy-http-challenge.herokuapp.com/api/v3/index");
xhr.setRequestHeader("User-Agent", "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)");
xhr.send(data);

第 15 關

這關就沒有題目了,非常感謝 鋰學院 開發這麼有趣的挑戰,對於像我這種菜雞來說非常有幫助XD,透過實際操作,終於開始可以搞懂一些一直很疑惑的概念了。

參考