Files
zogo/jwtx/jwt.go
T

62 lines
1.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Package jwtx 轻量 JWT(HMAC-SHA256),无外部依赖。
package jwtx
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"errors"
"strings"
"time"
)
// Claims 登录令牌载荷。
type Claims struct {
Uid int64 `json:"uid"`
Exp int64 `json:"exp"`
Msg string `json:"msg,omitempty"`
}
var secret = []byte("zo-maintain-jwt-secret-2026")
// Sign 签发 token(TTL 秒)。
func Sign(uid int64, ttlSeconds int64) (string, error) {
payload, err := json.Marshal(Claims{Uid: uid, Exp: time.Now().Add(time.Duration(ttlSeconds) * time.Second).Unix()})
if err != nil {
return "", err
}
body := base64.RawURLEncoding.EncodeToString(payload)
sig := sign(body)
return body + "." + sig, nil
}
// Parse 校验并解析 token。
func Parse(token string) (*Claims, error) {
parts := strings.SplitN(token, ".", 2)
if len(parts) != 2 {
return nil, errors.New("令牌格式错误")
}
if sign(parts[0]) != parts[1] {
return nil, errors.New("令牌签名校验失败")
}
payload, err := base64.RawURLEncoding.DecodeString(parts[0])
if err != nil {
return nil, errors.New("令牌载荷解析失败")
}
var c Claims
if err = json.Unmarshal(payload, &c); err != nil {
return nil, errors.New("令牌载荷解析失败")
}
if c.Exp < time.Now().Unix() {
return nil, errors.New("令牌已过期")
}
return &c, nil
}
func sign(body string) string {
mac := hmac.New(sha256.New, secret)
mac.Write([]byte(body))
return base64.RawURLEncoding.EncodeToString(mac.Sum(nil))
}