提供密钥验证,有效期刷新
gopackage jwt
import (
"errors"
goJwt "github.com/golang-jwt/jwt/v4"
"im-services/internal/config"
"im-services/pkg/logger"
"time"
)
// JWT struct represents the JSON Web Token configuration.
type JWT struct {
SigningKey []byte
MaxRefresh time.Duration
}
// CustomClaims struct defines custom claims for the JWT.
type CustomClaims struct {
ID int64 `json:"id"`
UID string `json:"uid"`
Name string `json:"name"`
Email string `json:"email"`
ExpireTime int64 `json:"expire_time"`
goJwt.StandardClaims // StandardClaims implements the Claims interface with Valid() method.
}
var (
TokenInvalid error = errors.New("Couldn't handle this token:")
)
// NewJWT creates a new JWT instance with configuration from the application.
func NewJWT() *JWT {
return &JWT{
SigningKey: []byte(config.Conf.JWT.Secret),
MaxRefresh: time.Duration(config.Conf.JWT.Ttl) * time.Minute,
}
}
// createToken generates a new JWT token with the provided custom claims.
func (j *JWT) createToken(claims CustomClaims) (string, error) {
token := goJwt.NewWithClaims(goJwt.SigningMethodHS256, claims)
res, err := token.SignedString(j.SigningKey)
return res, err
}
// ParseToken parses the provided JWT token string and returns the custom claims.
func (j *JWT) ParseToken(tokenString string) (*CustomClaims, error) {
token, err := goJwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *goJwt.Token) (interface{}, error) {
return j.SigningKey, nil
})
if err != nil {
return nil, err
}
if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
return claims, nil
}
return nil, TokenInvalid
}
// RefreshToken refreshes the provided JWT token string and returns the new token.
func (j *JWT) RefreshToken(tokenString string) (string, error) {
goJwt.TimeFunc = func() time.Time {
return time.Unix(0, 0)
}
token, err := goJwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *goJwt.Token) (interface{}, error) {
return j.SigningKey, nil
})
if err != nil {
return "", err
}
if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
goJwt.TimeFunc = time.Now
claims.StandardClaims.ExpiresAt = time.Now().Add(1 * time.Hour).Unix()
return j.createToken(*claims)
}
return "", TokenInvalid
}
// IssueToken generates a new JWT token with the provided user information and expiration time.
func (jwt *JWT) IssueToken(ID int64, UID string, Name string, Email string, expireAtTime int64) string {
claims := CustomClaims{
ID,
UID,
Name,
Email,
expireAtTime,
goJwt.StandardClaims{
NotBefore: time.Now().Unix(),
IssuedAt: time.Now().Unix(),
ExpiresAt: expireAtTime,
Issuer: config.Conf.Server.Name,
},
}
token, err := jwt.createToken(claims)
if err != nil {
logger.Logger.DPanic(err.Error())
return ""
}
return token
}
第二个模板,差不多
gopackage utils
import (
"errors"
"gin-blog/config"
"time"
"github.com/golang-jwt/jwt/v4"
)
// 定义 token 相关 error
var (
ErrTokenExpired = errors.New("token 已过期, 请重新登录")
ErrTokenNotValidYet = errors.New("token 无效, 请重新登录")
ErrTokenMalformed = errors.New("token 不正确, 请重新登录")
ErrTokenInvalid = errors.New("这不是一个 token, 请重新登录")
)
// 定义 JWT 中存储的信息
type MyClaims struct {
UserId int `json:"user_id"`
Role string `json:"role"`
UUID string `json:"uuid"`
jwt.RegisteredClaims
}
type MyJWT struct {
Secret []byte
}
// JWT 工具类
func GetJWT() *MyJWT {
return &MyJWT{[]byte(config.Cfg.JWT.Secret)}
}
// 生成 JWT
func (j *MyJWT) GenToken(userId int, role string, uuid string) (string, error) {
claims := MyClaims{
UserId: userId,
Role: role,
UUID: uuid,
RegisteredClaims: jwt.RegisteredClaims{
Issuer: config.Cfg.JWT.Issuer,
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(config.Cfg.JWT.Expire) * time.Hour)),
},
}
// 使用指定的签名方法创建签名对象
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
// 使用指定的 secret 签名并获得完整编码后的字符串 token
return token.SignedString(j.Secret)
}
// 解析 JWT
func (j *MyJWT) ParseToken(tokenString string) (*MyClaims, error) {
token, err := jwt.ParseWithClaims(tokenString, &MyClaims{}, func(t *jwt.Token) (interface{}, error) {
return j.Secret, nil
})
if err != nil {
if vError, ok := err.(*jwt.ValidationError); ok {
if vError.Errors&jwt.ValidationErrorMalformed != 0 {
return nil, ErrTokenMalformed
} else if vError.Errors&jwt.ValidationErrorExpired != 0 {
return nil, ErrTokenExpired
} else if vError.Errors&jwt.ValidationErrorNotValidYet != 0 {
return nil, ErrTokenNotValidYet
} else {
return nil, ErrTokenInvalid
}
}
}
// 校验 token
if claims, ok := token.Claims.(*MyClaims); ok && token.Valid {
return claims, nil
}
return nil, ErrTokenInvalid
}
本文作者:yowayimono
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!