这是我参与「第三届青训营 -后端场」笔记创作活动的第4篇笔记
项目安全策略
1、SQL注入预防
SQL注入的预防策略有两点:
1. SQL预编译:
项目中的SQL语句拼接为了实现防注入,全部实现了预编译,示例如下:
/*SQL语句全部以预编译的方式编写:*/
err := model.DB.Table("follow").
Select("user.id, user.nickname, user.follow_count, user.follower_count").
Joins("join user on follow.follower_id = user.id").
Where("follow_id = ?", userId).
Scan(&users).Error
2. 参数类型格式化(format)
项目中的SQL语句拼接为了实现防注入,在预编译的基础上进一步实现了参数format,示例如下:
/*参数vedioId、userId以int64型参数注入,非string类型:*/
func (c FavoriteRepository) IsFavorite(vedioId int64, userId int64) bool {
var count int64
model.DB.Table("favorite").Where("video_id = ? and user_id = ?", vedioId, userId).Count(&count)
return count != 0
}
2、token规则
Token规则的实现借助jwt-go 框架实现 链接jwt.io 对 JSON Web Tokens有很好的介绍 简而言之,它是一个签名的 JSON 对象,可以做一些验证(例如,身份验证) 令牌由三个部分组成,由 .'s 分隔。
前两部分是 JSON 对象,已经过base64url编码。 第一部分称为标题。它包含验证最后一部分签名的必要信息。 中间的部分是声明,包含您关心的实际内容。 最后一部分是签名,以同样的方式编码。
token签发
/*token签发操作*/
nowTime := time.Now()
expireTime := nowTime.Add(24000 * time.Hour)
claims := Claims{
Id: id,
Username: username,
Authority: authority,
StandardClaims: jwt.StandardClaims{
ExpiresAt: expireTime.Unix(),
Issuer: "Douyin",
},
}
tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
token, err := tokenClaims.SignedString(jwtSecret)
return token, err
token校验
/*token校验操作*/
claims, err := util.ParseToken(token)
if err != nil {
code = e.ErrorAuthCheckTokenFail
return serializer.CommentActionResponse{
Response: serializer.Response{StatusCode: code, StatusMsg: e.GetMsg(code)},
}
} else if time.Now().Unix() > claims.ExpiresAt {
code = e.ErrorAuthCheckTokenTimeout
return serializer.CommentActionResponse{
Response: serializer.Response{StatusCode: code, StatusMsg: e.GetMsg(code)},
}
}
userId := claims.Id
3、用户越权风险
水平越权风险
由于本项目只存在一类用户(User),因此不存在多用户之间的水平越权问题
垂直越权风险
用户由登录态和未登录态两种调用状态,直接可能存在的越权问题由Token规则提供保障
4、数据库索引检查
数据库的索引作为重要的安全和性能保障工作,由我们团队完成索引的设计和维护以保证数据库高效运行
5、数据库敏感数据保护
用户密码在数据库中以加盐后的散列值存储 验证过程由jwt-go 框架辅助实现,salt值不直接存储在Mysql数据库中从而实现数据库去敏感化