diff --git a/api/errcode/errcode.go b/api/errcode/errcode.go index ee278698..4daf4307 100644 --- a/api/errcode/errcode.go +++ b/api/errcode/errcode.go @@ -251,6 +251,10 @@ var ErrCodeMsgMap = map[ErrCode]string{ ErrCodeEmailSrvFail: "电子邮件表服务错误", ErrCodeEmailNotExist: "电子邮件表不存在", + ErrCodeVeriCodeWrongTimesSrvFail: "验证码错误频次表服务错误", + ErrCodeVeriCodeWrongTimesNotExist: "验证码错误频次表不存在", + ErrCodeVeriCodeWrongTimesReachedDailyUpperbound: "账户已锁定,请明日再试", + ErrCodeRavenIQTestSrvFail: "瑞文智商测试表服务错误", ErrCodeRavenIQTestNotExist: "瑞文智商测试表不存在", ErrCodeRavenIQTestQuestionNotExist: "瑞文智商测试表题目不存在", @@ -599,6 +603,12 @@ const ( ErrCodeEmailSrvFail ErrCode = -45001 // 电子邮件表服务错误 ErrCodeEmailNotExist ErrCode = -45002 // 电子邮件表不存在 + // MomentCreateTimes: 49xxx + ErrCodeVeriCodeWrongTimesSrvOk ErrCode = ErrCodeOk + ErrCodeVeriCodeWrongTimesSrvFail ErrCode = -49001 // 验证码错误频次表服务错误 + ErrCodeVeriCodeWrongTimesNotExist ErrCode = -49002 // 验证码错误频次表不存在 + ErrCodeVeriCodeWrongTimesReachedDailyUpperbound ErrCode = -49003 // 验证码错误次数已达每日上限 + // Media: 60xxx ErrCodeMediaSrvOk ErrCode = ErrCodeOk ErrCodeMediaSrvFail ErrCode = -60001 // 媒体服务错误 diff --git a/app/mix/dao/mongo.go b/app/mix/dao/mongo.go index fdae8f3c..565c2476 100644 --- a/app/mix/dao/mongo.go +++ b/app/mix/dao/mongo.go @@ -6458,6 +6458,24 @@ func (m *Mongo) GetAndUpdateVeriCodeWrongTimes(ctx *gin.Context, mid int64) (ver return &veriCodeWrongTimesInstance, err } +// 验证码错误频次 +func (m *Mongo) GetVeriCodeWrongTimes(ctx *gin.Context, id int64) (*dbstruct.VeriCodeWrongTimes, error) { + veriCodeWrongTimes := &dbstruct.VeriCodeWrongTimes{} + + col := m.getColVeriCodeWrongTimes() + query := qmgo.M{ + "_id": id, + } + + err := col.Find(ctx, query).One(veriCodeWrongTimes) + if err == qmgo.ErrNoSuchDocuments { + err = nil + return nil, err + } + + return veriCodeWrongTimes, err +} + // 删除验证码错误频次表 func (m *Mongo) DeleteVeriCodeWrongTimes(ctx *gin.Context, id int64) error { col := m.getColVeriCodeWrongTimes() diff --git a/app/mix/service/apiservice_business_validation.go b/app/mix/service/apiservice_business_validation.go index 9b558b84..bd54af06 100644 --- a/app/mix/service/apiservice_business_validation.go +++ b/app/mix/service/apiservice_business_validation.go @@ -97,11 +97,12 @@ func (s *Service) ApiLoginByVeriCodeBusinessValidate(ctx *gin.Context, req *logi // 1.业务校验 req.CalcPhoneHash() //计算手机号哈希 resultList := businessvalidator.NewLoginBusinessValidator(ctx, req). + QueryLogin(_DefaultLogin.OpListByPhoneHash). + EnsureVeriCodeWrongTimesNotReachedDailyUpperbound(_DefaultVeriCodeWrongTimes.OpGet). QueryVeriCode(_DefaultVeriCode.OpListByPhoneHash). EnsureVeriCodeExist(). - EnsureVeriCodeIsCorrect(). + EnsureVeriCodeIsCorrect(_DefaultVeriCodeWrongTimes.OpGetAndUpdate). EnsureVeriCodeIsValid(). - QueryLogin(_DefaultLogin.OpListByPhoneHash). EnsureLoginExist(). //EnsureLoginAcctNotLocked(). //验证码登录不校验是否爆破登录 EnsureLoginAcctNotBanned(). @@ -111,15 +112,7 @@ func (s *Service) ApiLoginByVeriCodeBusinessValidate(ctx *gin.Context, req *logi Collect() ec, _ = resultList[0].(errcode.ErrCode) - // 2.验证码错误处理 - if ec == errcode.ErrCodeLoginWrongPswd { - login, _ := resultList[1].(*dbstruct.Login) - if err := _DefaultLogin.OpHandleWrongPswd(ctx, login); err != nil { - logger.Error("OpHandleWrongPswd failed, err : %v", err) - } - } - - // 3.如果错误码是登录信息不存在,则判断为首次登录,业务逻辑将创建用户信息 + // 2.如果错误码是登录信息不存在,则判断为首次登录,业务逻辑将创建用户信息 if ec == errcode.ErrCodeLoginNotExist { vericode, _ = resultList[3].(*dbstruct.VeriCode) return @@ -169,12 +162,13 @@ func (s *Service) ApiResetPasswordBusinessValidate(ctx *gin.Context, req *loginp // 1.业务校验 req.CalcPhoneHash() //计算手机号哈希 resultList := businessvalidator.NewLoginBusinessValidator(ctx, req). - QueryVeriCode(_DefaultVeriCode.OpListByPhoneHash). - EnsureVeriCodeExist(). - EnsureVeriCodeIsCorrect(). - EnsureVeriCodeIsValid(). QueryLogin(_DefaultLogin.OpListByPhoneHash). EnsureLoginExist(). + EnsureVeriCodeWrongTimesNotReachedDailyUpperbound(_DefaultVeriCodeWrongTimes.OpGet). + QueryVeriCode(_DefaultVeriCode.OpListByPhoneHash). + EnsureVeriCodeExist(). + EnsureVeriCodeIsCorrect(_DefaultVeriCodeWrongTimes.OpGetAndUpdate). + EnsureVeriCodeIsValid(). EnsureLoginAcctEnabled(). EnsureLoginAcctNotBanned(). EnsureNewPasswordIsChanged(). @@ -203,12 +197,13 @@ func (s *Service) ApiUpdatePasswordBusinessValidate(ctx *gin.Context, req *login // 1.业务校验 req.CalcPhoneHash() //计算手机号哈希 resultList := businessvalidator.NewLoginBusinessValidator(ctx, req). - QueryVeriCode(_DefaultVeriCode.OpListByPhoneHash). - EnsureVeriCodeExist(). - EnsureVeriCodeIsCorrect(). - EnsureVeriCodeIsValid(). QueryLogin(_DefaultLogin.OpListByPhoneHash). EnsureLoginExist(). + EnsureVeriCodeWrongTimesNotReachedDailyUpperbound(_DefaultVeriCodeWrongTimes.OpGet). + QueryVeriCode(_DefaultVeriCode.OpListByPhoneHash). + EnsureVeriCodeExist(). + EnsureVeriCodeIsCorrect(_DefaultVeriCodeWrongTimes.OpGetAndUpdate). + EnsureVeriCodeIsValid(). EnsureLoginAcctEnabled(). EnsureLoginAcctNotLocked(). EnsureLoginAcctNotBanned(). @@ -709,7 +704,7 @@ func (s *Service) ApiCreateZoneThirdPartnerBusinessValidate(ctx *gin.Context, re resultList := businessvalidator.NewLoginBusinessValidator(ctx, req). QueryVeriCode(_DefaultVeriCode.OpListByPhoneHash). EnsureVeriCodeExist(). - EnsureVeriCodeIsCorrect(). + EnsureVeriCodeIsCorrect(_DefaultVeriCodeWrongTimes.OpGetAndUpdate). EnsureVeriCodeIsValid(). Validate(). Collect() diff --git a/app/mix/service/business_validator/login.go b/app/mix/service/business_validator/login.go index 30fd75c1..af3c5533 100644 --- a/app/mix/service/business_validator/login.go +++ b/app/mix/service/business_validator/login.go @@ -107,6 +107,35 @@ func (l *LoginBusinessValidator) EnsureLoginAcctNotBanned() *LoginBusinessValida return l } +func (l *LoginBusinessValidator) EnsureVeriCodeWrongTimesNotReachedDailyUpperbound(fun func(*gin.Context, int64) (*dbstruct.VeriCodeWrongTimes, error)) *LoginBusinessValidator { + l.oplist = append(l.oplist, func() { + + if l.login != nil { + // 读取每日错误上限 + maxDailyWrongTimes, err := apollo.GetIntValue(consts.MaxVeriCodeWrongTimesKey, apollo.ApolloOpts().SetNamespace("application")) + if err != nil { + logger.Error("Apollo read failed : %v", err) + l.ec = errcode.ErrCodeApolloReadFail + return + } + + wrongTimes, err := fun(l.ctx, l.login.GetMid()) + if err != nil { + l.ec = errcode.ErrCodeVeriCodeWrongTimesSrvFail + return + } + + if wrongTimes.WrongTimes >= int64(maxDailyWrongTimes) { + logger.Error("wrongs times of verification code of this mid has reached its daily upperbound") + l.ec = errcode.ErrCodeVeriCodeWrongTimesReachedDailyUpperbound + return + } + } + + }) + return l +} + func (l *LoginBusinessValidator) EnsurePasswordIsCorrect() *LoginBusinessValidator { l.oplist = append(l.oplist, func() { if l.passwordAccessor.GetPassword() != util.DerefString(l.login.Password) { @@ -194,10 +223,19 @@ func (l *LoginBusinessValidator) EnsureVeriCodeExist() *LoginBusinessValidator { return l } -func (l *LoginBusinessValidator) EnsureVeriCodeIsCorrect() *LoginBusinessValidator { +func (l *LoginBusinessValidator) EnsureVeriCodeIsCorrect(fun func(*gin.Context, int64) (*dbstruct.VeriCodeWrongTimes, error)) *LoginBusinessValidator { l.oplist = append(l.oplist, func() { if l.vericode.VeriCode != l.vericodeAccessor.GetVeriCode() { logger.Error("Wrong verification code") + + // 如果不是首次登录,则错误次数+1 + if l.login != nil { + _, err := fun(l.ctx, l.login.GetMid()) + if err != nil { + logger.Error("GetAndUpdateVeriCodeWrongTimes failed, err :%v", err) + } + } + l.ec = errcode.ErrCodeLoginWrongVeriCode return } diff --git a/app/mix/service/logic/veri_code_wrong_times.go b/app/mix/service/logic/veri_code_wrong_times.go index 98b6f6d8..18c7d43c 100644 --- a/app/mix/service/logic/veri_code_wrong_times.go +++ b/app/mix/service/logic/veri_code_wrong_times.go @@ -19,6 +19,17 @@ func NewVeriCodeWrongTimes(store *dao.Store) (a *VeriCodeWrongTimes) { return } +func (p *VeriCodeWrongTimes) OpGet(ctx *gin.Context, mid int64) (*dbstruct.VeriCodeWrongTimes, error) { + + veriCodeWrongTimes, err := p.store.GetVeriCodeWrongTimes(ctx, mid) + if err != nil { + logger.Error("GetVeriCodeWrongTimes fail, err: %v", err) + return nil, err + } + + return veriCodeWrongTimes, nil +} + func (p *VeriCodeWrongTimes) OpGetAndUpdate(ctx *gin.Context, mid int64) (*dbstruct.VeriCodeWrongTimes, error) { veriCodeWrongTimes, err := p.store.GetAndUpdateVeriCodeWrongTimes(ctx, mid) diff --git a/app/mix/service/opservice_business_validation.go b/app/mix/service/opservice_business_validation.go index 86b69fa8..4f2948fe 100644 --- a/app/mix/service/opservice_business_validation.go +++ b/app/mix/service/opservice_business_validation.go @@ -106,11 +106,12 @@ func (s *Service) OpLoginByVeriCodeBusinessValidate(ctx *gin.Context, req *login // 1.业务校验 req.CalcPhoneHash() //计算手机号哈希 resultList := businessvalidator.NewLoginBusinessValidator(ctx, req). + QueryLogin(_DefaultLogin.OpListByPhoneHash). + EnsureVeriCodeWrongTimesNotReachedDailyUpperbound(_DefaultVeriCodeWrongTimes.OpGet). QueryVeriCode(_DefaultVeriCode.OpListByPhoneHash). EnsureVeriCodeExist(). - EnsureVeriCodeIsCorrect(). + EnsureVeriCodeIsCorrect(_DefaultVeriCodeWrongTimes.OpGetAndUpdate). EnsureVeriCodeIsValid(). - QueryLogin(_DefaultLogin.OpListByPhoneHash). EnsureLoginExist(). EnsureLoginAcctNotLocked(). EnsureLoginAcctNotBanned(). @@ -172,12 +173,13 @@ func (s *Service) OpResetPasswordBusinessValidate(ctx *gin.Context, req *loginpr // 1.业务校验 req.CalcPhoneHash() //计算手机号哈希 resultList := businessvalidator.NewLoginBusinessValidator(ctx, req). - QueryVeriCode(_DefaultVeriCode.OpListByPhoneHash). - EnsureVeriCodeExist(). - EnsureVeriCodeIsCorrect(). - EnsureVeriCodeIsValid(). QueryLogin(_DefaultLogin.OpListByPhoneHash). EnsureLoginExist(). + EnsureVeriCodeWrongTimesNotReachedDailyUpperbound(_DefaultVeriCodeWrongTimes.OpGet). + QueryVeriCode(_DefaultVeriCode.OpListByPhoneHash). + EnsureVeriCodeExist(). + EnsureVeriCodeIsCorrect(_DefaultVeriCodeWrongTimes.OpGetAndUpdate). + EnsureVeriCodeIsValid(). EnsureLoginAcctEnabled(). EnsureLoginAcctNotBanned(). EnsureNewPasswordIsChanged(). @@ -207,12 +209,13 @@ func (s *Service) OpUpdatePasswordBusinessValidate(ctx *gin.Context, req *loginp // 1.业务校验 req.CalcPhoneHash() //计算手机号哈希 resultList := businessvalidator.NewLoginBusinessValidator(ctx, req). - QueryVeriCode(_DefaultVeriCode.OpListByPhoneHash). - EnsureVeriCodeExist(). - EnsureVeriCodeIsCorrect(). - EnsureVeriCodeIsValid(). QueryLogin(_DefaultLogin.OpListByPhoneHash). EnsureLoginExist(). + EnsureVeriCodeWrongTimesNotReachedDailyUpperbound(_DefaultVeriCodeWrongTimes.OpGet). + QueryVeriCode(_DefaultVeriCode.OpListByPhoneHash). + EnsureVeriCodeExist(). + EnsureVeriCodeIsCorrect(_DefaultVeriCodeWrongTimes.OpGetAndUpdate). + EnsureVeriCodeIsValid(). EnsureLoginAcctEnabled(). EnsureLoginAcctNotLocked(). EnsureLoginAcctNotBanned(). diff --git a/app/mix/service/service.go b/app/mix/service/service.go index 60a5b403..4bd89dce 100644 --- a/app/mix/service/service.go +++ b/app/mix/service/service.go @@ -154,6 +154,7 @@ var ( _DefaultEmail *logic.Email _DefaultRavenIQTest *logic.RavenIQTest _DefaultRavenIQTestVisit *logic.RavenIQTestVisit + _DefaultVeriCodeWrongTimes *logic.VeriCodeWrongTimes _DefaultStreamerDecrtByEs *logic.StreamerDecrtByEs _DefaultZoneDecrtByEs *logic.ZoneDecrtByEs diff --git a/app/mix/service/utilservice.go b/app/mix/service/utilservice.go index ce664c65..0c80440b 100644 --- a/app/mix/service/utilservice.go +++ b/app/mix/service/utilservice.go @@ -2208,46 +2208,3 @@ func (s *Service) UtilEncryptVideosForZoneMomentVOs(ctx *gin.Context, list []*zo } } } - -// 处理验证码错误 -func (p *Service) utilHandleWrongVeriCode(ctx *gin.Context, login *dbstruct.Login) error { - - //将验证码错误次数+1 - loginUpdate := &dbstruct.Login{ - Id: goproto.Int64(util.DerefInt64(login.Id)), - WrongPswdTimes: goproto.Int64(util.DerefInt64(login.WrongPswdTimes) + 1), - } - - //读取验证码最大错误次数 - maxVeriCodeWrongTimes, err := apollo.GetIntValue(consts.MaxVeriCodeWrongTimesKey, apollo.ApolloOpts().SetNamespace("application")) - if err != nil { - logger.Error("Apollo read failed : %v", err) - return err - } - - //若达到最大密码错误限制,锁定账户 - if util.DerefInt64(loginUpdate.WrongPswdTimes) == int64(maxVeriCodeWrongTimes) { - logger.Error("Verification cdoe wrong times have reached the limit, this account will be locked!") - loginUpdate.IsLocked = goproto.Int64(1) - } - - //更新账户 - if err := p.OpUpdate(ctx, &loginproto.OpUpdateReq{ - Login: loginUpdate, - }); err != nil { - logger.Error("Update wrong password times failed : %v", err) - return err - } - - return nil -} - -// 抹去密码错误次数 -func (p *Login) OpClearWrongPswdTimes(ctx *gin.Context) error { - err := p.store.ClearLoginWrongPswdTimes(ctx) - if err != nil { - logger.Error("Clear wrong password times failed : %v", err) - return err - } - return err -} diff --git a/dbstruct/login.go b/dbstruct/login.go index f66915be..8ee84be4 100644 --- a/dbstruct/login.go +++ b/dbstruct/login.go @@ -16,3 +16,10 @@ type Login struct { Ut *int64 `json:"ut" bson:"ut"` // 更新时间 DelFlag *int64 `json:"del_flag" bson:"del_flag"` // 删除标记,0-否,1-是 } + +func (p *Login) GetMid() int64 { + if p == nil || p.Mid == nil { + return -1 + } + return *p.Mid +}