diff --git a/api/proto/login/proto/login_api.go b/api/proto/login/proto/login_api.go index 5da120d4..dff9e69b 100644 --- a/api/proto/login/proto/login_api.go +++ b/api/proto/login/proto/login_api.go @@ -91,7 +91,8 @@ type ApiLoginResp struct { type ApiLogoutReq struct { base.BaseRequest - Mid *int64 `json:"mid"` // mid + TokenUuid int64 + Mid *int64 `json:"mid"` // mid } type ApiLogoutData struct { diff --git a/api/proto/login/proto/login_op.go b/api/proto/login/proto/login_op.go index b55c9a03..389b41ec 100644 --- a/api/proto/login/proto/login_op.go +++ b/api/proto/login/proto/login_op.go @@ -105,7 +105,8 @@ type OpLoginResp struct { type OpLogoutReq struct { base.BaseRequest - Mid *int64 `json:"mid"` // mid + TokenUuid int64 + Mid *int64 `json:"mid"` // mid } type OpLogoutData struct { diff --git a/app/mix/controller/login_api.go b/app/mix/controller/login_api.go index 464e9c17..e5ca5581 100644 --- a/app/mix/controller/login_api.go +++ b/app/mix/controller/login_api.go @@ -94,6 +94,7 @@ func ApiLoginByVeriCode(ctx *gin.Context) { func ApiLogout(ctx *gin.Context) { req := ctx.MustGet("client_req").(*loginproto.ApiLogoutReq) + req.TokenUuid = ctx.MustGet("token_uuid").(int64) logoutData, ec := service.DefaultService.ApiLogout(ctx, req) if ec != errcode.ErrCodeLoginSrvOk { logger.Error("ApiLogout fail, req: %v, ec: %v", util.ToJson(req), ec) diff --git a/app/mix/controller/login_op.go b/app/mix/controller/login_op.go index 64711dfe..040a573d 100644 --- a/app/mix/controller/login_op.go +++ b/app/mix/controller/login_op.go @@ -95,6 +95,7 @@ func OpLoginByVeriCode(ctx *gin.Context) { func OpLogout(ctx *gin.Context) { req := ctx.MustGet("client_req").(*loginproto.OpLogoutReq) + req.TokenUuid = ctx.MustGet("token_uuid").(int64) logoutData, ec := service.DefaultService.OpLogout(ctx, req) if ec != errcode.ErrCodeLoginSrvOk { logger.Error("OpLogout fail, req: %v, ec: %v", util.ToJson(req), ec) diff --git a/app/mix/service/apiservice.go b/app/mix/service/apiservice.go index 543d2e85..3768c48b 100644 --- a/app/mix/service/apiservice.go +++ b/app/mix/service/apiservice.go @@ -100,10 +100,9 @@ func (s *Service) ApiLoginByPswd(ctx *gin.Context, req *loginproto.ApiLoginByPsw // 2.让已登录的用户强制下线 if account.GetRole() == consts.User { - if _, ec = s.ApiLogout(ctx, &loginproto.ApiLogoutReq{ - Mid: account.Mid, - }); ec != errcode.ErrCodeLoginSrvOk { - logger.Error("ApiLogout failed!") + if err := s.utilLogoutAll(ctx, account.GetMid()); err != nil { + logger.Error("utilLogoutAll failed, err: %v", err) + ec = errcode.ErrCodeLoginSrvOk return } } @@ -175,10 +174,9 @@ func (s *Service) ApiLoginByVeriCode(ctx *gin.Context, req *loginproto.ApiLoginB // 4.让已登录的用户强制下线 if account.GetRole() == consts.User { - if _, ec = s.ApiLogout(ctx, &loginproto.ApiLogoutReq{ - Mid: account.Mid, - }); ec != errcode.ErrCodeLoginSrvOk { - logger.Error("ApiLogout failed!") + if err := s.utilLogoutAll(ctx, account.GetMid()); err != nil { + logger.Error("utilLogoutAll failed, err: %v", err) + ec = errcode.ErrCodeLoginSrvOk return } } @@ -218,8 +216,8 @@ func (s *Service) ApiLogout(ctx *gin.Context, req *loginproto.ApiLogoutReq) (log ec = errcode.ErrCodeLoginSrvOk - if err := _DefaultToken.OpDeleteByMid(ctx, util.DerefInt64(req.Mid)); err != nil && err != qmgo.ErrNoSuchDocuments { - logger.Error("ApiDeleteByMid failed, err: %v", err) + if err := _DefaultToken.OpDelete(ctx, req.TokenUuid); err != nil && err != qmgo.ErrNoSuchDocuments { + logger.Error("OpDelete failed, err: %v", err) logoutData = &loginproto.OpLogoutData{ OpResult: false, } @@ -227,18 +225,6 @@ func (s *Service) ApiLogout(ctx *gin.Context, req *loginproto.ApiLogoutReq) (log return } - // 更新登录状态 - if err := _DefaultLogin.OpUpdateByMid(ctx, &loginproto.OpUpdateByMidReq{ - Login: &dbstruct.Login{ - IsLogined: goproto.Int64(0), - }, - Mid: req.Mid, - }); err != nil { - ec = errcode.ErrCodeLoginSrvFail - logger.Error("ApiUpdateByMid failed, err: %v", err) - return - } - logoutData = &loginproto.OpLogoutData{ OpResult: true, } diff --git a/app/mix/service/logic/token.go b/app/mix/service/logic/token.go index 52deae54..407fdc1f 100644 --- a/app/mix/service/logic/token.go +++ b/app/mix/service/logic/token.go @@ -103,29 +103,29 @@ func (p *Token) OpGenerate(ctx *gin.Context, req *tokenproto.OpCreateReq) (token return } -func (p *Token) OpVerify(ctx *gin.Context, tokenString string) error { +func (p *Token) OpVerify(ctx *gin.Context, tokenString string) (int64, error) { //是否携带令牌 if tokenString == "" { logger.Error("Missing auth token") - return fmt.Errorf("missing auth token") + return -1, fmt.Errorf("missing auth token") } //检查令牌加密方法及签名 token, err := p.OpVerifyCrypto(ctx, tokenString) if err != nil { logger.Error("OpVerifyCrypto failed") - return err + return -1, err } //检查数据库中是否还存在该token(是否还有效) - err = p.OpVerifyValid(ctx, token) + id, err := p.OpVerifyValid(ctx, token) if err != nil { logger.Error("OpVerifyValid failed") - return err + return -1, err } - return nil + return id, nil } // 检查令牌加密方法及签名 @@ -144,29 +144,29 @@ func (p *Token) OpVerifyCrypto(ctx *gin.Context, tokenString string) (token *jwt } // 检查该token是否还有效 -func (p *Token) OpVerifyValid(ctx *gin.Context, token *jwt.Token) error { +func (p *Token) OpVerifyValid(ctx *gin.Context, token *jwt.Token) (int64, error) { claims, ok := token.Claims.(jwt.MapClaims) if !ok { - return fmt.Errorf("Token type assertion failed") + return -1, fmt.Errorf("Token type assertion failed") } if !token.Valid { - return fmt.Errorf("Token is invalid") + return -1, fmt.Errorf("Token is invalid") } tokenUuid, err := strconv.ParseInt(fmt.Sprintf("%.f", claims["token_uuid"]), 10, 64) if err != nil { - return fmt.Errorf("failed to acquire token_uuid from token") + return -1, fmt.Errorf("failed to acquire token_uuid from token") } list, err := p.OpList(ctx, &tokenproto.OpListReq{ Id: tokenUuid, }) if err != nil { - return fmt.Errorf("OpList failed") + return -1, fmt.Errorf("OpList failed") } if len(list) == 0 { - return fmt.Errorf("登录失效,请重新登录!") + return -1, fmt.Errorf("登录失效,请重新登录!") } - return nil + return tokenUuid, nil } diff --git a/app/mix/service/service.go b/app/mix/service/service.go index 60e924a7..58fe4fb0 100644 --- a/app/mix/service/service.go +++ b/app/mix/service/service.go @@ -713,8 +713,8 @@ func (s *Service) OpLogout(ctx *gin.Context, req *loginproto.OpLogoutReq) (logou ec = errcode.ErrCodeLoginSrvOk - if err := _DefaultToken.OpDeleteByMid(ctx, util.DerefInt64(req.Mid)); err != nil && err != qmgo.ErrNoSuchDocuments { - logger.Error("OpDeleteByMid failed, err: %v", err) + if err := _DefaultToken.OpDelete(ctx, req.TokenUuid); err != nil && err != qmgo.ErrNoSuchDocuments { + logger.Error("ApiDeleteByMid failed, err: %v", err) logoutData = &loginproto.OpLogoutData{ OpResult: false, } @@ -722,18 +722,6 @@ func (s *Service) OpLogout(ctx *gin.Context, req *loginproto.OpLogoutReq) (logou return } - // 更新登录状态 - if err := _DefaultLogin.OpUpdateByMid(ctx, &loginproto.OpUpdateByMidReq{ - Login: &dbstruct.Login{ - IsLogined: goproto.Int64(0), - }, - Mid: req.Mid, - }); err != nil { - ec = errcode.ErrCodeLoginSrvFail - logger.Error("OpUpdateByMid failed, err: %v", err) - return - } - logoutData = &loginproto.OpLogoutData{ OpResult: true, } @@ -1034,8 +1022,8 @@ func (s *Service) OpGetAccountCount(ctx *gin.Context, req *accountproto.OpCountR } // Token -func (s *Service) OpVerifyToken(ctx *gin.Context, token string) (err error) { - if err = _DefaultToken.OpVerify(ctx, token); err != nil { +func (s *Service) OpVerifyToken(ctx *gin.Context, token string) (id int64, err error) { + if id, err = _DefaultToken.OpVerify(ctx, token); err != nil { logger.Error("OpVerifyToken fail, err :%v", err) return } diff --git a/app/mix/service/utilservice.go b/app/mix/service/utilservice.go index 682b5a8c..ff226e59 100644 --- a/app/mix/service/utilservice.go +++ b/app/mix/service/utilservice.go @@ -2061,3 +2061,24 @@ func (s *Service) utilSignHvyogoMessage(msg interfaces.HvyogoSignable) ([]byte, return resultBytes, nil } + +func (s *Service) utilLogoutAll(ctx *gin.Context, mid int64) (err error) { + + if err = _DefaultToken.OpDeleteByMid(ctx, mid); err != nil && err != qmgo.ErrNoSuchDocuments { + logger.Error("ApiDeleteByMid failed, err: %v", err) + return + } + + // 更新登录状态 + if err = _DefaultLogin.OpUpdateByMid(ctx, &loginproto.OpUpdateByMidReq{ + Login: &dbstruct.Login{ + IsLogined: goproto.Int64(0), + }, + Mid: goproto.Int64(mid), + }); err != nil { + logger.Error("ApiUpdateByMid failed, err: %v", err) + return + } + + return +} diff --git a/library/middleware/jwt_authenticator.go b/library/middleware/jwt_authenticator.go index b2f85048..ee9cd774 100644 --- a/library/middleware/jwt_authenticator.go +++ b/library/middleware/jwt_authenticator.go @@ -12,7 +12,7 @@ var ( DefaultJwtAuthenticator gin.HandlerFunc ) -func InitJwtAuthenticator(verifyFunc func(*gin.Context, string) error) { +func InitJwtAuthenticator(verifyFunc func(*gin.Context, string) (int64, error)) { DefaultJwtAuthenticator = func(ctx *gin.Context) { //1.获取token @@ -25,11 +25,12 @@ func InitJwtAuthenticator(verifyFunc func(*gin.Context, string) error) { logger.Info("token : %v", tokenString) //2.校验 - err := verifyFunc(ctx, tokenString) + id, err := verifyFunc(ctx, tokenString) if !base.CheckBadRequest(ctx, err) { return } + ctx.Set("token_uuid", id) ctx.Next() } }