Files
novel_server/utility/jwt/jwt.go

79 lines
1.7 KiB
Go

package jwt
import (
"errors"
"server/utility/ecode"
"strings"
"time"
"github.com/golang-jwt/jwt/v5"
"github.com/google/uuid"
)
var (
secretKey = []byte("1a40c1d5b7a1b0f0fasdfaf835e0b24ca292a6")
issuer = "novel"
)
type (
TokenIn struct {
UserId int64 // 用户 ID
Role string // 权限标识
}
TokenOut struct {
UserId int64 // 用户 ID
Role string // 权限标识
JTI string // JWT 唯一标识
}
jwtClaims struct {
UserId int64 `json:"user_id"` // 用户 ID
Role string `json:"Role"` // 权限标识
JTI string `json:"jti"` // 唯一标识
jwt.RegisteredClaims
}
)
func GenerateToken(in *TokenIn) (string, error) {
claims := jwtClaims{
UserId: in.UserId,
Role: in.Role,
JTI: uuid.NewString(),
RegisteredClaims: jwt.RegisteredClaims{
IssuedAt: jwt.NewNumericDate(time.Now()),
NotBefore: jwt.NewNumericDate(time.Now()),
Issuer: issuer,
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString(secretKey)
}
func ParseToken(tokenString string) (*TokenOut, error) {
if strings.HasPrefix(tokenString, "Bearer ") {
tokenString = strings.TrimPrefix(tokenString, "Bearer ")
}
token, err := jwt.ParseWithClaims(tokenString, &jwtClaims{}, func(token *jwt.Token) (interface{}, error) {
return secretKey, nil
})
if err != nil {
if errors.Is(err, jwt.ErrTokenExpired) {
return nil, ecode.Expire.Sub("token_expired")
}
return nil, ecode.Fail.Sub("token_parse_failed")
}
claims, ok := token.Claims.(*jwtClaims)
if !ok || !token.Valid {
return nil, ecode.InvalidOperation.Sub("invalid_token")
}
return &TokenOut{
UserId: claims.UserId,
Role: claims.Role,
JTI: claims.JTI,
}, nil
}