106 lines
2.9 KiB
Go
106 lines
2.9 KiB
Go
package tools
|
|
|
|
import (
|
|
"crypto/ecdsa"
|
|
"errors"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/golang-jwt/jwt/v5"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
const (
|
|
HeaderNonce = "X-NONCE"
|
|
HeaderSign = "X-S-SIGN"
|
|
|
|
TypeResource = "RESOURCE" // 资源权限
|
|
TypeInterface = "INTERFACE" // 接口权限
|
|
TypeData = "DATA" // 数据权限
|
|
|
|
HeaderUserId = "X-USER-ID"
|
|
HeaderScopeId = "X-SCOPE-ID"
|
|
HeaderScopeCode = "X-SCOPE"
|
|
HeaderUsername = "X-USERNAME"
|
|
HeaderNickname = "X-NICKNAME"
|
|
HeaderClient = "X-CLIENT"
|
|
|
|
ClientAdminCompany = "ADMIN_COMPANY"
|
|
ClientAdminAppUser = "APP_USER"
|
|
ClientAdminAppDriver = "APP_DRIVER"
|
|
)
|
|
|
|
const (
|
|
iss = "anxpp.com"
|
|
secret = `-----BEGIN ECD PRIVATE KEY-----
|
|
MHcCAQEEIDjrRKvb5a6Klcqi38w5vQMZZluja1DTOG+UFrh3hRxfoAoGCCqGSM49AwEHoUQDQgAEt6K29uBUrZmM4Sdyw/w9d2EUk1kiV8YM+tmGkuVyXQ+qFcbl7f4V1UMbKzXsqmyCPxgFBaeN61/nxdi99Ds4bw==
|
|
-----END ECD PRIVATE KEY-----`
|
|
pk = `-----BEGIN ECD PUBLIC KEY-----
|
|
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEt6K29uBUrZmM4Sdyw/w9d2EUk1kiV8YM+tmGkuVyXQ+qFcbl7f4V1UMbKzXsqmyCPxgFBaeN61/nxdi99Ds4bw==
|
|
-----END ECD PUBLIC KEY-----`
|
|
)
|
|
|
|
type Claims struct {
|
|
Username string `json:"un,omitempty"`
|
|
Nickname string `json:"nn,omitempty"`
|
|
Client string `json:"cli,omitempty"`
|
|
jwt.RegisteredClaims
|
|
}
|
|
|
|
func (c Claims) NeedRefresh(d time.Duration) bool {
|
|
return c.ExpiresAt.Before(time.Now().Add(d))
|
|
}
|
|
|
|
func GenerateToken(client, uid, username, nickname string, exp, nbf, iat time.Time, aud []string) (tokenStr string, e error) {
|
|
token := jwt.NewWithClaims(jwt.SigningMethodES256, &Claims{
|
|
Username: username,
|
|
Nickname: nickname,
|
|
Client: client,
|
|
RegisteredClaims: jwt.RegisteredClaims{
|
|
Issuer: iss, // 令牌发行者
|
|
Subject: uid, // 统一用户ID
|
|
Audience: aud, // 受众
|
|
ExpiresAt: &jwt.NumericDate{Time: exp}, // 过期时间
|
|
NotBefore: &jwt.NumericDate{Time: nbf}, // 启用时间
|
|
IssuedAt: &jwt.NumericDate{Time: iat}, // 发布时间
|
|
ID: JwtID(), // jwt ID
|
|
},
|
|
})
|
|
var ecdsaKey *ecdsa.PrivateKey
|
|
if ecdsaKey, e = jwt.ParseECPrivateKeyFromPEM([]byte(secret)); e != nil {
|
|
panic(e)
|
|
}
|
|
tokenStr, e = token.SignedString(ecdsaKey)
|
|
return
|
|
}
|
|
|
|
func VerifyToken(tokenStr string) (access bool, claims Claims, e error) {
|
|
var ecdsaKeyPub *ecdsa.PublicKey
|
|
if ecdsaKeyPub, e = jwt.ParseECPublicKeyFromPEM([]byte(pk)); e != nil {
|
|
return
|
|
}
|
|
var token *jwt.Token
|
|
if token, e = jwt.ParseWithClaims(tokenStr, &claims, func(token *jwt.Token) (any, error) {
|
|
return ecdsaKeyPub, nil
|
|
}); e != nil {
|
|
return
|
|
}
|
|
access = token.Valid
|
|
return
|
|
}
|
|
|
|
func JwtID() string {
|
|
u4 := uuid.New()
|
|
return strings.ReplaceAll(u4.String(), "-", "")
|
|
}
|
|
|
|
func ParseAuthToken(jwt string) (access bool, claims Claims, e error) {
|
|
// jwt := c.GetHeader("Authorization")
|
|
fields := strings.Fields(jwt)
|
|
if len(fields) < 2 {
|
|
e = errors.New("wrong token")
|
|
return
|
|
}
|
|
return VerifyToken(fields[1])
|
|
}
|