flipped-aurora/gin-vue-admin · error

token尚未激活

Error message

token尚未激活

What it means

TokenNotValidYet is returned by ParseToken when the token's nbf (not-before) claim is later than the current time. The token is structurally valid but is being used before its activation window opens.

Solutions

  1. Sync clocks on both issuing and validating machines (chrony/NTP).
  2. Re-issue a token without a future nbf if immediate use is intended.
  3. If pre-issued (future-nbf) tokens are intentional, delay client use until after nbf.

Example fix

// before
jwtClaims := ... // token minted with future nbf on skewed host
claims, err := utils.ParseToken(token) // token尚未激活
// after
// ntpdate / chronyc makestep  -> clocks aligned
// re-issue token with nbf <= now
claims, err := utils.ParseToken(token) // ok
Defensive patterns

Strategy: try-catch

Validate before calling

if payload["nbf"] && payload["nbf"]*1000 > Date.now() {
    return errors.New("token not active yet; check clocks or issue time")
}

Try / catch

claims, err := utils.ParseToken(token)
if errors.Is(err, utils.TokenNotValidYet) {
    // clock skew likely: alert ops to sync NTP; do not accept the token early
    return nil, ErrTokenNotActive
}

Prevention

When it happens

Trigger: A token issued with a future nbf/iat is presented immediately; server clock is behind the issuing server's clock, so a token issued 'now' by machine A looks not-yet-valid on machine B.

Common situations: Clock skew between issuing and validating servers or between a token minted on a machine with a fast clock; pre-issued tokens with an intentional future nbf used too early; containers with wrong timezone/UTC offsets.

Related errors


AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31). Data as JSON: /api/errors/061b6721f983c820. Report an issue: GitHub.

Appendix: source

Thrown at server/utils/jwt.go:20

import (
	"context"
	"errors"
	"time"

	"github.com/flipped-aurora/gin-vue-admin/server/global"
	"github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
	jwt "github.com/golang-jwt/jwt/v5"
)

type JWT struct {
	SigningKey []byte
}

var (
	TokenValid            = errors.New("未知错误")
	TokenExpired          = errors.New("token已过期")
	TokenNotValidYet      = errors.New("token尚未激活")
	TokenMalformed        = errors.New("这不是一个token")
	TokenSignatureInvalid = errors.New("无效签名")
	TokenInvalid          = errors.New("无法处理此token")
)

func NewJWT() *JWT {
	return &JWT{
		[]byte(global.GVA_CONFIG.JWT.SigningKey),
	}
}

func (j *JWT) CreateClaims(baseClaims request.BaseClaims) request.CustomClaims {
	bf, _ := ParseDuration(global.GVA_CONFIG.JWT.BufferTime)
	ep, _ := ParseDuration(global.GVA_CONFIG.JWT.ExpiresTime)
	claims := request.CustomClaims{
		BaseClaims: baseClaims,
		BufferTime: int64(bf / time.Second), // 缓冲时间1天 缓冲时间内会获得新的token刷新令牌 此时一个用户会存在两个有效令牌 但是前端只留一个 另一个会丢失
		RegisteredClaims: jwt.RegisteredClaims{

View on GitHub (pinned to 3136500ef3)