|
|
|
package jwt
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"git.diulo.com/mogfee/kit/errors"
|
|
|
|
"git.diulo.com/mogfee/kit/internal/xuuid"
|
|
|
|
"github.com/golang-jwt/jwt/v5"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
// iss : jwt签发者
|
|
|
|
// sub : 主题名称
|
|
|
|
// aud : 面向的用户,一般都是通过ip或者域名控制
|
|
|
|
// exp : jwt的有效时间(过期时间),这个有效时间必须要大于签发时间,对于交互接口来说,建议是预设5秒
|
|
|
|
// nbf : 在什么时候jwt开始生效(在此之前不可用)
|
|
|
|
// iat : jwt的签发时间
|
|
|
|
// jti : 唯一标识,主要用来回避被重复使用攻击
|
|
|
|
|
|
|
|
type UserInfo struct {
|
|
|
|
UserId string
|
|
|
|
UserName string
|
|
|
|
UserType string
|
|
|
|
Permissions []string
|
|
|
|
UniqueId string
|
|
|
|
}
|
|
|
|
|
|
|
|
func GetToken(key string, info *UserInfo) (token string, uniqId string, err error) {
|
|
|
|
uniqId = xuuid.UUID()
|
|
|
|
info.UniqueId = uniqId
|
|
|
|
var tokenStr string
|
|
|
|
ctime := time.Now().Unix()
|
|
|
|
tokenStr, err = jwt.NewWithClaims(jwt.SigningMethodHS256, &jwt.MapClaims{
|
|
|
|
//jwt签发者
|
|
|
|
//"iss": "auth.diulo.com",
|
|
|
|
//主题名称
|
|
|
|
//"sub": "www.diulo.com",
|
|
|
|
// 面向的用户,一般都是通过ip或者域名控制
|
|
|
|
//"aud": "api.diulo.com",
|
|
|
|
//jwt的有效时间(过期时间),这个有效时间必须要大于签发时间,对于交互接口来说,建议是预设5秒
|
|
|
|
"exp": ctime + 7200,
|
|
|
|
//在什么时候jwt开始生效(在此之前不可用)
|
|
|
|
"nbf": ctime,
|
|
|
|
//jwt的签发时间
|
|
|
|
"iat": ctime,
|
|
|
|
//唯一标识,主要用来回避被重复使用攻击
|
|
|
|
"jti": uniqId,
|
|
|
|
"info": info,
|
|
|
|
}).SignedString([]byte(key))
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
token, err = Encrypt(tokenStr, []byte(key), key)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func Parse(key string, tokenStr string) (*UserInfo, error) {
|
|
|
|
if tokenStr == "" {
|
|
|
|
return &UserInfo{}, nil
|
|
|
|
}
|
|
|
|
str, err := Decrypt(tokenStr, []byte(key), key)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
token, err := jwt.Parse(str, func(token *jwt.Token) (interface{}, error) {
|
|
|
|
return []byte(key), nil
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
if errors.Is(err, jwt.ErrTokenExpired) {
|
|
|
|
return nil, errors.Unauthorized("TOKEN_EXPIRED", "")
|
|
|
|
}
|
|
|
|
return nil, errors.Unauthorized("TOKEN_ERROR", err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
if token.Valid {
|
|
|
|
row := struct {
|
|
|
|
Info *UserInfo
|
|
|
|
}{}
|
|
|
|
b, _ := json.Marshal(token.Claims)
|
|
|
|
if err = json.Unmarshal(b, &row); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return row.Info, nil
|
|
|
|
} else if errors.Is(err, jwt.ErrTokenExpired) || errors.Is(err, jwt.ErrTokenNotValidYet) {
|
|
|
|
return nil, errors.Unauthorized("TOKEN_EXPIRED", "")
|
|
|
|
}
|
|
|
|
return nil, errors.Unauthorized("TOKEN_ERROR", "")
|
|
|
|
}
|