golang编程常见问题
1. gitlab/github提交非项目文件(如编译后的二进制文件).
使用.gitignore来忽略提交的文件
2. 使用字符串拼接JSON问题
举例:
responseString := "{ \"code\" : \"0\" , \"data\": { \"username\": " + username + " }}"
return []byte(responseString)
如上代码块,因username从外部传入,有JSON注入风险,最佳方法为:使用json.Marshal结构体封装返回值
// 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提交的数据,对输入参数校验不足
需要对输入参数做校验,通常使用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. 函数结构中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, 不应该在if判断逻辑体内,应该放在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服务时,需要设计为长连接模式,并实现线程安全的连接池。
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来代替重复的else if:
var functionMap = map[string]interface{} {
"A” == funcA,
"B" == funcB,
"C" == funcC,
"D" == funcD
}
functionMap[functionName].(func())()
8. 使用cookie时,未实现安全的session Token问题。
Session Token可考虑使用 随机数+时间戳+随机值,并设置有效期。
9. 密码存储应哈希加盐,防止彩虹攻击。
通过前端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. 避免重复代码,注意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