Go-Web程式設計_表單_0x02_驗證表單的輸入

TheSky9531發表於2020-11-25

開發Web的一個原則就是,不能信任使用者輸入的任何資訊,所以驗證和過濾使用者的輸入資訊就變得非常重要,我們經常會在微博、新聞中聽到某某網站被入侵了,存在什麼漏洞,這些大多是因為網站對於使用者輸入的資訊沒有做嚴格的驗證引起的,所以為了編寫出安全可靠的Web程式,驗證表單輸入的意義重大。

我們平常編寫Web應用主要有兩方面的資料驗證,一個是在頁面端的js驗證(目前在這方面有很多的外掛庫,比如ValidationJS外掛),一個是在伺服器端的驗證,我們主要考慮的是如克在伺服器端驗證

 

必填欄位


你想要確保從一個表單元素中得到一個值,例如前面小結裡面的使用者名稱,我們如何處理呢?Go有一個內建函式len可以獲取字串的長度,這樣我們就可以通過len來獲取資料的長度,例如:

if len(r.Form["username"][0]==0{
  //為空的處理  
}

  r.Form對不同型別的表單元素的留空有不同的處理,對於空文字框、空白本區域及檔案上傳,元素的值為空值,而如果是未選中的核取方塊和單選按鈕,則根本不會在r.Form中產生相應條目,如果我們用上面例子中的方式去獲取資料時程式就會報錯。所以我們需要通過r.Form.Get()來獲取值,因為如果欄位不存在,通過該方式獲取的是空值。但是通過r.Form.Get()只能獲取單個的值,如果是map的值,必須通過上面的方式來獲取。

數字


 


你想要的確保一個表單輸入框中獲取的只能是數字,例如,你想通過表單獲取某個人的具體年齡是50歲還是10歲,而不是像“一把年紀了”或“年輕著呢”這種描述

如果我們是判斷正整數,那麼我們先轉化成int型別,然後進行處理

getint,err:=strconv.Atoi(r.Form.Get("age"))
if err!=nil{
    //數字轉化出錯了,那麼可能就不是數字
}
//接下來就可以判斷這個數字的大小範圍了
if getint>100{
//太大了
}

  

還有一種方式就是正則匹配的方式

if m,_ :=regexp.MatchString("^[0-9]+$",r.Form.Get("age"));!m{
    return false
}

  

對於效能要求很高的使用者來說,這是一個老生常談的問題了,他們認為應該儘量避免使用正規表示式,因為使用正規表示式的速度會比較慢。但是在目前機器效能那麼強勁的情況下,對於這種簡單的正規表示式效率和型別轉換函式式沒有什麼差別的。如果你對正規表示式很熟悉,而且你在其他語言中也在使用它,那麼在Go裡面使用正規表示式講師一個遍歷的方式。

Go實現的正則是RE2,所有的字元都是UTF-8編碼的。

 

中文


 

有時候我們想通過表單元素獲取一個使用者的中文名字,但是又為了保證獲取的是正確的中文,我們需要進行驗證,而不是使用者隨便的一些輸入。對於中文我們目前有兩種方式來驗證,也可以使用正則方式來驗證,這裡使用最簡單的正則方式,如下程式碼所示

if m,_:= regexp.MatchString("^\\p{Han}+$",r.Form.Get("realname"));!m{
    return false
}

  

英文


 

我們期望通過表單元素獲取一個英文值,例如我們想知道一個使用者的英文名,應該是astaxie,而不是asta謝。

 

 

電子郵件地址


 

你想知道使用者輸入的一個Email地址是否正確,通過如下這個方式可以驗證:

 

 

手機號碼


 

你想要的判斷使用者輸入的手機號碼是否正確,通過正則也可以驗證:

 

 

下拉選單


 

如果我們想要判斷表單裡面<select>元素生成的下拉選單是否有備選中的專案。有些時候黑客可能回偽造這個下拉選單不存在的值傳送給你,那麼如果判斷這個值是否是我們預設的值呢?

我們的select可能是這樣的一些元素

 

 那麼我們可以這樣來驗證

 

 

單選按鈕


 

如果我們想要判斷radio按鈕是否有一個被選中了,我們頁面的輸出可能就是一個男、女性別的選擇,但可能是一個15歲打的無聊小孩,一手拿著http協議的書,另一手通過telnet客戶端向你的程式在傳送請求呢,你設定的性別男值是1,女是2,他給你傳送一個3,你的程式會出現異常嗎?因此我們也需要像下拉選單的判斷方式類似,判斷我們獲取的值使我們預設的值,而不是額外的值。

那我們也可以類似下來選單的做法一樣

 

 

核取方塊


 

有一項選擇興趣的核取方塊,你想確定使用者選中的和你提供給使用者的選擇是用一個型別的資料。

 

 

對於核取方塊我們的驗證和單選有點不一樣,因為接收到的資料是一個sliece

 

 

上面這個函式Slice_diff包含在開源的一個庫裡面(操作slice和map的庫)

https://github.com/astaxie/beeku

 

日期和時間


你想確定使用者填寫的日期或時間是否有效。例如,使用者在日程表中安排8月份的第45天開會,或者提供未來的某個時間作為生日。

Go裡面提供了一個time的處理包,我們可以把使用者的輸入年月日轉化成響應的時間,然後進行邏輯判斷

 

 獲取time之後我們就可以進行很多時間函式的操作。具體的判斷就根據自己的需求調整。

 

身份證號碼


 

如果我們想要雁陣個表單輸入的是否是身份證,通過正則也可以方便的驗證,但是身份證有15位和18位,我們兩個都要驗證

 

 上面列出了我們一些常用的伺服器端的表單元素驗證,特別是Go裡面的正則處理。

 

相關文章