1. gitlab/github提交非項(xiàng)目文件(如編譯后的二進(jìn)制文件).
? ? 使用.gitignore來忽略提交的文件
2.? 使用字符串拼接JSON問題
舉例:
responseString := "{ \"code\" : \"0\" , \"data\": { \"username\": " + username + " }}"?
return []byte(responseString)
如上代碼塊,因username從外部傳入,有JSON注入風(fēng)險,最佳方法為:使用json.Marshal結(jié)構(gòu)體封裝返回值
// JSONStyle return http.data like json style
type JSONStyle struct {? ?
? ? Code string `json:"code"`????
? ? Data struct {????????
? ? ? ? Username string `json:"username"`?
? ? ?}? `json:"data"
}
var jsonData JSONStyle
jsonData.Code = code
jsonData.Data.Username = username
result, err := json.Marshal(jsonData)
if err != nil {?
? ?fmt.Println("struct convert to json bytes fail")
? ? return nil
}
return result
3. 針對form提交的數(shù)據(jù),對輸入?yún)?shù)校驗(yàn)不足
? 需要對輸入?yún)?shù)做校驗(yàn),通常使用form validation的一些庫,如?github.com/astaxie/beego/validation
username := req.Form.Get("username")
userpass := req.Form.Get("userpass")
valid := validation.Validation{}
valid.Length(userpass, 32, "userpass")?
valid.MinSize(username, 6, "username")
valid.MaxSize(username, 20, "username")
4. 函數(shù)結(jié)構(gòu)中if嵌套過多,正常返回包含在if中
舉例:
username = req.Form.Get("username")?
userpass = req.Form.Get("password")
?if username != "" {?
? ? user := LoginIn(username, userpass)?
? ? if (user != nil) && (user.Username != "") {?
? ? ? ? //if login success, cookie data to mem.?
? ? ? ? return true
? ? }
}?
return false
此例子中,正常邏輯為return true, 不應(yīng)該在if判斷邏輯體內(nèi),應(yīng)該放在if外的主體程序中。以下為更正效果:
username = req.Form.Get("username")?
userpass = req.Form.Get("password")?
if username == "" {? ? ?
? ? return false
}
user := LoginIn(username, userpass)
if (user == nil) || (user.Username == "") {
? ? return false? ?
}
return true
5. 使用TCP服務(wù)時,需要設(shè)計(jì)為長連接模式,并實(shí)現(xiàn)線程安全的連接池。
6. 在tcpclient和tcpserver之間,封裝TCP請求方法,傳入interface{},返回inetrface{}
7. else if 過多問題
舉例:
if funtionName == "A" {
? ? return funcA
} else if?funtionName == "B" {
? ? return funcB
}?else if?funtionName == "C" {? ?
? ? return funcC
}?else if?funtionName == "D"
{?
? ? return funcD
}
使用map來代替重復(fù)的else if:
var functionMap = map[string]interface{} {
? ? "A” ==?funcA,
? ? "B" == funcB,
? ? "C" == funcC,
? ? "D"? == funcD
}
functionMap[functionName].(func())()
8. 使用cookie時,未實(shí)現(xiàn)安全的session Token問題。
? ? Session Token可考慮使用 隨機(jī)數(shù)+時間戳+隨機(jī)值,并設(shè)置有效期。
9. 密碼存儲應(yīng)哈希加鹽,防止彩虹攻擊。
通過前端js請求舉例:
md5.update(this.userpass)
var userpass = md5.digest('hex')? ? //第一次加密
var salt = "ny1XH"?
var md5 = crypto.createHash('md5')?
md5.update(userpass+salt)? ?
userpass = md5.digest('hex')???//第二次加鹽加密
10. 避免重復(fù)代碼,注意DRY(Don’t Repeat Yourself)和KISS原則(Keep?It?Simple,?Stupid)。
? ? 參考:
? ??https://zh.wikipedia.org/wiki/%E4%B8%80%E6%AC%A1%E4%B8%94%E4%BB%85%E4%B8%80%E6%AC%A1