Files
2026-11-07 10:46:18 +08:00

128 lines
2.7 KiB
Go

package utils
import (
"errors"
"strings"
"time"
"github.com/dgrijalva/jwt-go"
)
const (
userIDKey = "userId"
ipKey = "ip"
uaKey = "ua"
)
type IPClaims struct {
Ip string
Expire time.Duration
UA string
}
func GenerateIpToken(claims IPClaims, secret string) (string, error) {
return generateToken(jwt.MapClaims{
ipKey: claims.Ip,
uaKey: claims.UA,
"exp": Now().Add(claims.Expire).Unix(),
"issuer": "com.butterfly",
"sub": "asign",
"aud": "public",
}, []byte(secret))
}
func ParseIpToken(tokenString string, secret string) (pass bool, ip, ua string, err error) {
t, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return []byte(secret), nil
})
var isExpire *bool
if vErr, ok := err.(*jwt.ValidationError); ok {
e := vErr.Errors&jwt.ValidationErrorExpired > 0
isExpire = &e
}
if err != nil || isExpire == nil {
return
}
var ok bool
var jc jwt.MapClaims
jc, ok = t.Claims.(jwt.MapClaims)
if !ok {
err = errors.New("parse token fail")
return
}
ip, ok = jc[ipKey].(string)
if !ok {
err = errors.New("parse token fail")
return
}
ua, ok = jc[uaKey].(string)
if !ok {
err = errors.New("parse token fail")
return
}
pass = true
return
}
type UserClaims struct {
UserID int64
Expire time.Duration
}
func generateToken(claims jwt.MapClaims, secret []byte) (string, error) {
return jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString(secret)
}
func GenerateUserToken(claims UserClaims, secret string) (string, error) {
return generateToken(jwt.MapClaims{
userIDKey: claims.UserID,
"exp": Now().Add(claims.Expire).Unix(),
"issuer": "com.butterfly",
"sub": "asign",
"aud": "public",
}, []byte(secret))
}
// ParseToken 解析Token
func ParseUserToken(token string, secret string) (userId int64, newToken string, err error) {
t, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
return []byte(secret), nil
})
var isExpire *bool
if vErr, ok := err.(jwt.ValidationError); ok {
e := vErr.Errors&jwt.ValidationErrorExpired > 0
isExpire = &e
}
if err != nil && isExpire == nil {
return
}
jc, ok := t.Claims.(jwt.MapClaims)
if !ok {
err = errors.New("unknown token error1")
return
}
id, ok := jc[userIDKey].(float64)
if !ok {
err = errors.New("unknown token error1")
return
}
userId = int64(id)
if isExpire != nil && *isExpire {
newToken, err = GenerateUserToken(UserClaims{UserID: userId, Expire: 30 * 24 * time.Hour}, secret)
return
}
err = nil
return
}
// Strips 'Bearer ' prefix from bearer token string
func StripBearerPrefixFromTokenString(tok string) string {
if len(tok) > 6 && strings.ToUpper(tok[0:7]) == "BEARER " {
return tok[7:]
} else {
return tok
}
}