轉載
Go基礎學習記錄 - 編寫Web應用程式 - 安全驗證
安全驗證
前面加了很多功能,但是程式存在嚴重的安全性漏洞,使用者可以訪問在伺服器上讀/寫的任意路徑。
為了緩解這種情況,我們可以編寫一個函數來使用Regex驗證標題。
首先,將"regexp"添加到匯入列表中。
然後我們可以建立一個全域變數來儲存我們的驗證運算式:
var validPath = regexp.MustCompile("^/(edit|save|view)/([a-zA-Z0-9]+)$")
函數regexp.MustCompile將解析並編譯Regex,並返回一個regexp.Regexp。
MustCompile與Compile的區別在於,如果運算式編譯失敗,它將會出現異常,而Compile會將錯誤作為第二個參數返回。
現在,讓我們編寫一個函數,該函數使用validPath運算式來驗證路徑並提取頁面標題
func getTitle(w http.ResponseWriter, r *http.Request) (string, error) { m := validPath.FindStringSubmatch(r.URL.Path) if m == nil { http.NotFound(w, r) return "", errors.New("無效的頁面標題") } return m[2], nil // 標題是第二個子運算式中}
如果標題有效,它將與nil錯誤值一起返回。
如果標題無效,該函數將向HTTP串連寫入“404 Not Found”錯誤,並向處理常式返回錯誤。
要建立新錯誤,我們必須匯入錯誤包。
下面在每個處理常式中調用getTitle:
func viewHandler(w http.ResponseWriter, r *http.Request) { title, err := getTitle(w, r) if err != nil { return } p, err := loadPage(title) if err != nil { http.Redirect(w, r, "/edit/"+title, http.StatusFound) return } renderTemplate(w, "view", p)}func editHandler(w http.ResponseWriter, r *http.Request) { title, err := getTitle(w, r) if err != nil { return } p, err := loadPage(title) if err != nil { p = &Page{Title: title} } renderTemplate(w, "edit", p)}func saveHandler(w http.ResponseWriter, r *http.Request) { title, err := getTitle(w, r) if err != nil { return } body := r.FormValue("body") p := &Page{ Title: title, Body: []byte(body), } err = p.save() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } http.Redirect(w, r, "/view/"+title, http.StatusFound)}
修改完之後,重新編譯並運行程式,當訪問非edit、view、save路由時,會出現異常錯誤提示