package sms import ( "context" "time" "bsm/full/module/base/sender/internal/excode" "bsm/full/module/base/sender/internal/impl" pb "bsm/full/module/base/sender/pb" "git.apinb.com/bsm-sdk/core/errcode" ) func Verify(ctx context.Context, in *pb.SmsVerifyRequest) (reply *pb.SmsReply, err error) { if in.GetCode() == "" { return nil, excode.ErrCode } if in.GetPhone() == "" { return nil, excode.ErrPhone } //check redis key := KeyPrefix + in.GetPhone() code, err := impl.RedisService.Client.Get(impl.RedisService.Ctx, key).Result() if err != nil { return nil, errcode.NewError(1311, err.Error()) } //check code if code == in.Code { // 校验成功:删除验证码与失败计数,验证码一次性使用,避免重放 failKey := VerifyFailCacheKey + in.GetPhone() impl.RedisService.Client.Del(impl.RedisService.Ctx, key) impl.RedisService.Client.Del(impl.RedisService.Ctx, failKey) return &pb.SmsReply{ Reply: "true", }, nil } // 校验失败:累计连续失败次数,达到上限后验证码作废,避免暴力枚举 failKey := VerifyFailCacheKey + in.GetPhone() count := impl.RedisService.Client.Incr(impl.RedisService.Ctx, failKey).Val() if count == 1 { ttl := impl.RedisService.Client.TTL(impl.RedisService.Ctx, key).Val() if ttl <= 0 { ttl = 300 * time.Second } impl.RedisService.Client.Expire(impl.RedisService.Ctx, failKey, ttl) } if count >= MaxVerifyFail { impl.RedisService.Client.Del(impl.RedisService.Ctx, key) impl.RedisService.Client.Del(impl.RedisService.Ctx, failKey) return nil, excode.ErrCodeVerifyTooMany } return &pb.SmsReply{ Reply: "false", }, nil }