补齐相关日志日志
This commit is contained in:
@@ -28,6 +28,8 @@ func JWTAuth() gin.HandlerFunc {
|
||||
// 1. 从 Authorization 头取 token:Bearer xxx.yyy.zzz
|
||||
authHeader := c.GetHeader("Authorization")
|
||||
if authHeader == "" {
|
||||
slog.WarnContext(c.Request.Context(), "jwt auth: authorization header missing",
|
||||
"method", c.Request.Method, "path", c.Request.URL.Path, "ip", c.ClientIP())
|
||||
response.ToErrorResponse(errcode.UnauthorizedTokenMissing)
|
||||
c.Abort()
|
||||
return
|
||||
@@ -35,6 +37,8 @@ func JWTAuth() gin.HandlerFunc {
|
||||
|
||||
parts := strings.SplitN(authHeader, " ", 2)
|
||||
if len(parts) != 2 || parts[0] != "Bearer" {
|
||||
slog.WarnContext(c.Request.Context(), "jwt auth: invalid authorization format",
|
||||
"method", c.Request.Method, "path", c.Request.URL.Path, "ip", c.ClientIP())
|
||||
response.ToErrorResponse(errcode.UnauthorizedTokenError.WithDetails("invalid Authorization format"))
|
||||
c.Abort()
|
||||
return
|
||||
@@ -45,10 +49,14 @@ func JWTAuth() gin.HandlerFunc {
|
||||
if err != nil {
|
||||
switch {
|
||||
case errors.Is(err, lzcwyjwt.ErrTokenExpired):
|
||||
slog.InfoContext(c.Request.Context(), "jwt auth: token expired", "path", c.Request.URL.Path)
|
||||
response.ToErrorResponse(errcode.UnauthorizedTokenTimeout)
|
||||
case errors.Is(err, lzcwyjwt.ErrTokenWrongType):
|
||||
slog.WarnContext(c.Request.Context(), "jwt auth: token type mismatch", "path", c.Request.URL.Path)
|
||||
response.ToErrorResponse(errcode.UnauthorizedTokenError.WithDetails("token type mismatch"))
|
||||
default:
|
||||
slog.WarnContext(c.Request.Context(), "jwt auth: parse token failed",
|
||||
"path", c.Request.URL.Path, "ip", c.ClientIP(), "error", err)
|
||||
response.ToErrorResponse(errcode.UnauthorizedTokenError.WithDetails(err.Error()))
|
||||
}
|
||||
c.Abort()
|
||||
@@ -59,6 +67,8 @@ func JWTAuth() gin.HandlerFunc {
|
||||
sessionUID, serr := redisdao.AuthUserIDByAccess(c.Request.Context(), parts[1])
|
||||
if serr != nil {
|
||||
if errors.Is(serr, redis.Nil) {
|
||||
slog.WarnContext(c.Request.Context(), "jwt auth: token session invalid",
|
||||
"user_id", claims.UserID, "path", c.Request.URL.Path)
|
||||
response.ToErrorResponse(errcode.UnauthorizedTokenError.WithDetails("token session invalid"))
|
||||
c.Abort()
|
||||
return
|
||||
@@ -67,8 +77,12 @@ func JWTAuth() gin.HandlerFunc {
|
||||
// 已确认的安全权衡决策——优先保证可用性,避免 Redis 抖动导致全员不可用。
|
||||
// 代价是 Redis 故障窗口内,已登出/被吊销但未过期的 token 仍可访问;
|
||||
// 封禁用户仍会被下方 DB 回查(Status != 1)拒绝,不会因本降级放行而绕过封禁。
|
||||
slog.WarnContext(c.Request.Context(), "check access token session failed, allow by fallback", "error", serr)
|
||||
slog.WarnContext(c.Request.Context(), "check access token session failed, allow by fallback",
|
||||
"user_id", claims.UserID, "path", c.Request.URL.Path, "ip", c.ClientIP(), "error", serr)
|
||||
} else if sessionUID != claims.UserID {
|
||||
slog.ErrorContext(c.Request.Context(), "jwt auth: token user mismatch",
|
||||
"user_id", claims.UserID, "session_user_id", sessionUID,
|
||||
"path", c.Request.URL.Path, "ip", c.ClientIP())
|
||||
response.ToErrorResponse(errcode.UnauthorizedTokenError.WithDetails("token user mismatch"))
|
||||
c.Abort()
|
||||
return
|
||||
@@ -78,21 +92,29 @@ func JWTAuth() gin.HandlerFunc {
|
||||
userInfo, err := redisdao.UserInfoGet(c.Request.Context(), claims.UserID)
|
||||
if err != nil {
|
||||
if !errors.Is(err, redis.Nil) {
|
||||
slog.WarnContext(c.Request.Context(), "get user info from cache failed, fallback to db", "error", err)
|
||||
slog.WarnContext(c.Request.Context(), "get user info from cache failed, fallback to db",
|
||||
"user_id", claims.UserID, "error", err)
|
||||
}
|
||||
// 缓存未命中或 Redis 抖动:回落数据库。
|
||||
dbUser, dbErr := mysqldao.NewUserDao().UserGetByID(c.Request.Context(), claims.UserID)
|
||||
if dbErr != nil {
|
||||
slog.WarnContext(c.Request.Context(), "jwt auth: query user failed",
|
||||
"user_id", claims.UserID, "path", c.Request.URL.Path, "error", dbErr)
|
||||
response.ToErrorResponse(errcode.UnauthorizedTokenError.WithDetails("用户不存在"))
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
userInfo = dbUser
|
||||
_ = redisdao.UserInfoSet(c.Request.Context(), dbUser, 0)
|
||||
if cerr := redisdao.UserInfoSet(c.Request.Context(), dbUser, 0); cerr != nil {
|
||||
slog.DebugContext(c.Request.Context(), "jwt auth: backfill user cache failed",
|
||||
"user_id", claims.UserID, "error", cerr)
|
||||
}
|
||||
}
|
||||
|
||||
// 状态非正常(1=正常)一律拒绝
|
||||
if userInfo.Status != 1 {
|
||||
slog.WarnContext(c.Request.Context(), "jwt auth: user disabled",
|
||||
"user_id", claims.UserID, "status", userInfo.Status, "path", c.Request.URL.Path)
|
||||
response.ToErrorResponse(errcode.UserDisabled)
|
||||
c.Abort()
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user