Go JWT 鉴权中间件:用 golang-jwt 签发校验并注入上下文

test12026-10-222 次阅读

签发 token:claims 里放最小必要信息

用 github.com/golang-jwt/jwt/v5 签发,密钥从配置读、不要硬编码。claims 里只放用户标识与过期时间,敏感字段不要塞进 token。

package auth

import (
    "time"

    "github.com/golang-jwt/jwt/v5"
)

var secret = []byte("change-me-in-config")

type claims struct {
    UserID int64 `json:"uid"`
    jwt.RegisteredClaims
}

func SignToken(userID int64) (string, error) {
    c := claims{
        UserID: userID,
        RegisteredClaims: jwt.RegisteredClaims{
            ExpiresAt: jwt.NewNumericDate(time.Now().Add(2 * time.Hour)),
            IssuedAt:  jwt.NewNumericDate(time.Now()),
        },
    }
    return jwt.NewWithClaims(jwt.SigningMethodHS256, c).SignedString(secret)
}

中间件校验并注入 context

在中间件里解析 token,失败直接 401;成功把 userID 写进 request context,下游 handler 用同一个 key 取,不靠全局变量。

package auth

import (
    "context"
    "net/http"
    "strings"

    "github.com/golang-jwt/jwt/v5"
)

type ctxKey struct{}

func Middleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        h := r.Header.Get("Authorization")
        if !strings.HasPrefix(h, "Bearer ") {
            http.Error(w, "missing token", http.StatusUnauthorized)
            return
        }
        tok, err := jwt.ParseWithClaims(strings.TrimPrefix(h, "Bearer "),
            &claims{}, func(t *jwt.Token) (interface{}, error) { return secret, nil })
        if err != nil || !tok.Valid {
            http.Error(w, "invalid token", http.StatusUnauthorized)
            return
        }
        uid := tok.Claims.(*claims).UserID
        ctx := context.WithValue(r.Context(), ctxKey{}, uid)
        next.ServeHTTP(w, r.WithContext(ctx))
    })
}

func UserID(r *http.Request) int64 {
    return r.Context().Value(ctxKey{}).(int64)
}

读取 claims

func Profile(w http.ResponseWriter, r *http.Request) {
    uid := auth.UserID(r)
    fmt.Fprintf(w, "user %d", uid)
}

关键结论

  • 密钥走配置,token 只带最小必要字段。
  • 解析失败统一 401,不要泄露具体原因。
  • 身份通过 context 传递,handler 内取用,避免全局状态。
T

test1

文章作者

签发 token:claims 里放最小必要信息 用 github.com/golang-jwt/jwt/v5 签发,密...

分类
技术
发布时间
2026-10-22
字数
约 1949 字
阅读
2 次