From b94b8b8e6a391f026538b3de36370182c3866e94 Mon Sep 17 00:00:00 2001 From: Jorbenzhu Date: Wed, 3 Jul 2024 16:13:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0auth/renew=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=EF=BC=8C=E6=94=AF=E6=8C=81=E5=88=B7=E6=96=B0jwt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - context中增加token的过期时间戳 - 增加auth/renew接口,刷新登录态token --- common/errs/errors.go | 2 ++ middleware/auth.go | 7 ++++++- router/api/auth.go | 29 +++++++++++++++++++++++++++++ service/authservice.go | 14 +++++++++----- 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/common/errs/errors.go b/common/errs/errors.go index 81b2287..44342fa 100644 --- a/common/errs/errors.go +++ b/common/errs/errors.go @@ -10,6 +10,7 @@ const ( ErrAuthLoginFailed = -10004 // 登录失败 ErrAuthNoLogin = -10005 // 未登录 ErrAuthUnauthorized = -10006 // 未授权 + ErrAuthUnexpired = -10007 // 未过期 ) // 定义错误码对应的错误描述 @@ -21,6 +22,7 @@ var errorMsg = map[int]string{ ErrAuthLoginFailed: "登录/注册失败,请稍后重试", ErrAuthNoLogin: "未登录或登录态已过期", ErrAuthUnauthorized: "未授权或权限不足", + ErrAuthUnexpired: "刷新登录态失败,当前登录态还有足够长的有效期", } // GetErrorMsg 获取错误码对应的错误描述 diff --git a/middleware/auth.go b/middleware/auth.go index 52bc2e2..e0dd489 100644 --- a/middleware/auth.go +++ b/middleware/auth.go @@ -12,14 +12,19 @@ import ( func Auth() gin.HandlerFunc { return func(ctx *gin.Context) { var userId string + var expiresAt int64 c := context.CustomContext{Context: ctx} tokenString := ctx.GetHeader("X-Token") authService := service.NewAuthService(ctx) if len(tokenString) > 0 { - userId, _ = authService.VerifyJwtString(tokenString) + if token, err := authService.VerifyJwtString(tokenString); err == nil { + userId = token.UserId + expiresAt = token.ExpiresAt + } } ctx.Set("UserId", userId) + ctx.Set("ExpiresAt", expiresAt) // 校验权限 path := ctx.Request.URL.Path diff --git a/router/api/auth.go b/router/api/auth.go index 3c63648..3572fea 100644 --- a/router/api/auth.go +++ b/router/api/auth.go @@ -10,6 +10,8 @@ import ( "league/provider/auth" "league/service" "net/http" + "strconv" + "time" ) // AuthProvider 第三方登录渠道接口 @@ -95,5 +97,32 @@ func AuthCallback(ctx *gin.Context) { // AuthRenew 续期JWT func AuthRenew(ctx *gin.Context) { + c := context.CustomContext{Context: ctx} + + strUserId := ctx.Value("UserId").(string) + userId, err := strconv.Atoi(strUserId) + if err != nil { + c.CJSON(errs.ErrAuthNoLogin) + return + } + expiresAt, ok := ctx.Value("ExpiresAt").(int64) + if !ok { + expiresAt = 0 + } + + now := time.Now() + if expiresAt-now.Unix() > 1*60*60 { + // 距离过期时间>1小时 不予刷新 + c.CJSON(errs.ErrAuthUnexpired) + return + } + + authService := service.NewAuthService(ctx) + token, err := authService.SignJwtString(uint(userId)) + if err != nil { + c.CJSON(errs.ErrAuthLoginFailed, "刷新token失败,请稍后重试") + return + } + c.CJSON(errs.Success, token) } diff --git a/service/authservice.go b/service/authservice.go index 9f5abab..13bfdd4 100644 --- a/service/authservice.go +++ b/service/authservice.go @@ -88,7 +88,7 @@ func (a *AuthService) SignJwtString(id uint) (*AuthToken, error) { token := jwt.NewWithClaims(jwt.SigningMethodHS384, claims) sign, err := token.SignedString(a.signKey) if err != nil { - log.Errorf(a.Ctx, "Jwt SignedString failed, err: %s", err.Error()) + log.Infof(a.Ctx, "Jwt SignedString failed, err: %s", err.Error()) return nil, err } return &AuthToken{ @@ -100,20 +100,24 @@ func (a *AuthService) SignJwtString(id uint) (*AuthToken, error) { } // VerifyJwtString 校验JWT -func (a *AuthService) VerifyJwtString(s string) (string, error) { +func (a *AuthService) VerifyJwtString(s string) (*AuthToken, error) { token, err := jwt.ParseWithClaims(s, &jwt.RegisteredClaims{}, func(token *jwt.Token) (interface{}, error) { return a.signKey, nil }) if err != nil { log.Errorf(a.Ctx, "Jwt parse failed, err: %s", err.Error()) - return "", err + return nil, err } else if claims, ok := token.Claims.(*jwt.RegisteredClaims); ok { log.Debugf(a.Ctx, "Check login passed, UserId: %s", claims.ID) - return claims.ID, nil + return &AuthToken{ + UserId: claims.ID, + ExpiresAt: claims.ExpiresAt.Unix(), + NotBefore: claims.NotBefore.Unix(), + }, nil } else { log.Errorf(a.Ctx, "Unknown claims type, token: %s", s) - return "", errors.New("unknown claims type") + return nil, errors.New("unknown claims type") } }