登录增加密码策略校验
This commit is contained in:
4
go.mod
4
go.mod
@@ -3,7 +3,7 @@ module github.com/tiger1103/gfast/v3
|
|||||||
go 1.26.0
|
go 1.26.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
gitea.com/red-future/common v0.0.18
|
gitea.com/red-future/common v0.0.21
|
||||||
github.com/asaskevich/EventBus v0.0.0-20200907212545-49d423059eef
|
github.com/asaskevich/EventBus v0.0.0-20200907212545-49d423059eef
|
||||||
github.com/casbin/casbin/v2 v2.42.0
|
github.com/casbin/casbin/v2 v2.42.0
|
||||||
github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.10.0
|
github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.10.0
|
||||||
@@ -16,7 +16,7 @@ require (
|
|||||||
github.com/tiger1103/gfast-token v1.0.10
|
github.com/tiger1103/gfast-token v1.0.10
|
||||||
)
|
)
|
||||||
|
|
||||||
//replace gitea.com/red-future/common v0.0.18 => ../common
|
//replace gitea.com/red-future/common v0.0.19 => ../common
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/BurntSushi/toml v1.5.0 // indirect
|
github.com/BurntSushi/toml v1.5.0 // indirect
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -1,6 +1,6 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
gitea.com/red-future/common v0.0.18 h1:RwpnnWmDTCnFtKfmlp9BOnDd4r9eUnx7YT6Zst3VJqY=
|
gitea.com/red-future/common v0.0.21 h1:8w30HmCVmFG/hphH3ODJs1KxDEGmRpq+/PXI0pQjJKc=
|
||||||
gitea.com/red-future/common v0.0.18/go.mod h1:6/nqIucVzmjOyqDTIq71feYBXXFNBy0rFwzaQ0/Ueoo=
|
gitea.com/red-future/common v0.0.21/go.mod h1:6/nqIucVzmjOyqDTIq71feYBXXFNBy0rFwzaQ0/Ueoo=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
|
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
|
||||||
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||||
|
|||||||
@@ -65,6 +65,9 @@ func (s *sSysUser) GetAdminUserByUsernamePassword(ctx context.Context, req *syst
|
|||||||
user, err = s.GetUserByUsername(ctx, req.Username)
|
user, err = s.GetUserByUsername(ctx, req.Username)
|
||||||
liberr.ErrIsNil(ctx, err)
|
liberr.ErrIsNil(ctx, err)
|
||||||
liberr.ValueIsNil(user, "账号密码错误")
|
liberr.ValueIsNil(user, "账号密码错误")
|
||||||
|
//验证密码复杂度
|
||||||
|
err = s.validatePasswordComplexity(ctx, req.Password)
|
||||||
|
liberr.ErrIsNil(ctx, err)
|
||||||
//验证密码
|
//验证密码
|
||||||
if libUtils.EncryptPassword(req.Password, user.UserSalt) != user.UserPassword {
|
if libUtils.EncryptPassword(req.Password, user.UserSalt) != user.UserPassword {
|
||||||
liberr.ErrIsNil(ctx, gerror.New("账号密码错误"))
|
liberr.ErrIsNil(ctx, gerror.New("账号密码错误"))
|
||||||
@@ -77,6 +80,101 @@ func (s *sSysUser) GetAdminUserByUsernamePassword(ctx context.Context, req *syst
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// validatePasswordComplexity 验证密码复杂度
|
||||||
|
func (s *sSysUser) validatePasswordComplexity(ctx context.Context, password string) (err error) {
|
||||||
|
dict, err := commonService.SysDictData().GetDictWithDataByType(ctx, &system.GetDictReq{
|
||||||
|
DictType: "pass_config",
|
||||||
|
})
|
||||||
|
if err != nil || dict == nil || len(dict.Values) == 0 {
|
||||||
|
// 如果没有配置密码复杂度,则默认放行
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
config := make(map[string]string)
|
||||||
|
for _, v := range dict.Values {
|
||||||
|
config[v.DictValue] = v.Remark
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否启用密码策略
|
||||||
|
if enabled, ok := config["enabled"]; ok && enabled != "true" {
|
||||||
|
// 未启用密码策略,直接放行
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证最小长度
|
||||||
|
if minLen, ok := config["min_length"]; ok {
|
||||||
|
if len(password) < gconv.Int(minLen) {
|
||||||
|
return gerror.Newf("密码长度不能少于%s位", minLen)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证最大长度
|
||||||
|
if maxLen, ok := config["max_length"]; ok {
|
||||||
|
if len(password) > gconv.Int(maxLen) {
|
||||||
|
return gerror.Newf("密码长度不能超过%s位", maxLen)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证是否需要包含数字
|
||||||
|
if needNumber, ok := config["need_number"]; ok && needNumber == "true" {
|
||||||
|
hasNumber := false
|
||||||
|
for _, c := range password {
|
||||||
|
if c >= '0' && c <= '9' {
|
||||||
|
hasNumber = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !hasNumber {
|
||||||
|
return gerror.New("密码必须包含数字")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证是否需要包含小写字母
|
||||||
|
if needLower, ok := config["need_lower"]; ok && needLower == "true" {
|
||||||
|
hasLower := false
|
||||||
|
for _, c := range password {
|
||||||
|
if c >= 'a' && c <= 'z' {
|
||||||
|
hasLower = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !hasLower {
|
||||||
|
return gerror.New("密码必须包含小写字母")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证是否需要包含大写字母
|
||||||
|
if needUpper, ok := config["need_upper"]; ok && needUpper == "true" {
|
||||||
|
hasUpper := false
|
||||||
|
for _, c := range password {
|
||||||
|
if c >= 'A' && c <= 'Z' {
|
||||||
|
hasUpper = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !hasUpper {
|
||||||
|
return gerror.New("密码必须包含大写字母")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证是否需要包含特殊字符
|
||||||
|
if needSpecial, ok := config["need_special"]; ok && needSpecial == "true" {
|
||||||
|
hasSpecial := false
|
||||||
|
specialChars := "!@#$%^&*()_+-=[]{}|;':\",./<>?`~"
|
||||||
|
for _, c := range password {
|
||||||
|
if gstr.Contains(specialChars, string(c)) {
|
||||||
|
hasSpecial = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !hasSpecial {
|
||||||
|
return gerror.New("密码必须包含特殊字符")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetUserByUsername 通过用户名获取用户信息
|
// GetUserByUsername 通过用户名获取用户信息
|
||||||
func (s *sSysUser) GetUserByUsername(ctx context.Context, userName string) (user *model.LoginUserRes, err error) {
|
func (s *sSysUser) GetUserByUsername(ctx context.Context, userName string) (user *model.LoginUserRes, err error) {
|
||||||
err = g.Try(ctx, func(ctx context.Context) {
|
err = g.Try(ctx, func(ctx context.Context) {
|
||||||
|
|||||||
Reference in New Issue
Block a user