github.com/binbinly/pkg@v0.0.11-0.20240321014439-f4fbf666eb0f/auth/jwt.go (about) 1 package auth 2 3 import ( 4 "context" 5 "time" 6 7 "github.com/golang-jwt/jwt/v5" 8 ) 9 10 // Payload is the data of the JSON web token. 11 // 主要是配合jwt来生成用户登录token 12 type Payload struct { 13 UserID int 14 } 15 16 // secretFunc validates the secret format. 17 func secretFunc(secret string) jwt.Keyfunc { 18 return func(token *jwt.Token) (any, error) { 19 // Make sure the `alg` is what we except. 20 if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { 21 return nil, jwt.ErrSignatureInvalid 22 } 23 24 return []byte(secret), nil 25 } 26 } 27 28 // Parse validates the token with the specified secret, 29 // and returns the payloads if the token was valid. 30 func Parse(tokenString string, secret string) (*Payload, error) { 31 // Parse the token. 32 token, err := jwt.Parse(tokenString, secretFunc(secret)) 33 if err != nil { 34 return nil, err 35 } 36 // Read the token if it's valid. 37 if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { 38 payloads := &Payload{} 39 payloads.UserID = int(claims["user_id"].(float64)) 40 return payloads, nil 41 } 42 43 // Other errors. 44 return nil, err 45 } 46 47 // Sign signs the payload with the specified secret. 48 func Sign(ctx context.Context, payload map[string]any, secret string, timeout int64) (tokenString string, err error) { 49 // The token content. 50 // iss: (Issuer)签发者 51 // iat: (Issued At)签发时间,用Unix时间戳表示 52 // exp: (Expiration Time)过期时间,用Unix时间戳表示 53 // aud: (Audience)接收该JWT的一方 54 // sub: (Subject)该JWT的主题 55 // nbf: (Not Before)不要早于这个时间 56 // jti: (JWT ID)用于标识JWT的唯一ID 57 now := time.Now().Unix() 58 claims := make(jwt.MapClaims) 59 claims["nbf"] = now 60 claims["iat"] = now 61 claims["exp"] = now + timeout 62 63 for k, v := range payload { 64 claims[k] = v 65 } 66 67 token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) 68 69 // Sign the token with the specified secret. 70 tokenString, err = token.SignedString([]byte(secret)) 71 72 return 73 }