first commit
This commit is contained in:
11
pkg/secure/auth.go
Normal file
11
pkg/secure/auth.go
Normal file
@ -0,0 +1,11 @@
|
||||
package secure
|
||||
|
||||
const (
|
||||
HeaderScopeCode = "X-SCOPE"
|
||||
HeaderNonce = "X-NONCE"
|
||||
HeaderSign = "X-S-SIGN"
|
||||
|
||||
TypeResource = "RESOURCE" // 资源权限
|
||||
TypeInterface = "INTERFACE" // 接口权限
|
||||
TypeData = "DATA" // 数据权限
|
||||
)
|
||||
86
pkg/secure/jwt.go
Normal file
86
pkg/secure/jwt.go
Normal file
@ -0,0 +1,86 @@
|
||||
package secure
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type Claims struct {
|
||||
Username string `json:"un,omitempty"`
|
||||
Nickname string `json:"nn,omitempty"`
|
||||
ExtID string `json:"ei,omitempty"`
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
func (c Claims) NeedRefresh(d time.Duration) bool {
|
||||
return c.ExpiresAt.Before(time.Now().Add(d))
|
||||
}
|
||||
|
||||
func GenerateToken(iss, uid, username, nickname string, exp, nbf, iat time.Time, aud []string, primaryKey string) (tokenStr string, e error) {
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodES256, &Claims{
|
||||
Username: username,
|
||||
Nickname: nickname,
|
||||
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(primaryKey)); e != nil {
|
||||
panic(e)
|
||||
}
|
||||
tokenStr, e = token.SignedString(ecdsaKey)
|
||||
return
|
||||
}
|
||||
|
||||
func GenerateTokenWithEID(iss, uid, username, nickname, eid string, exp, nbf, iat time.Time, aud []string, primaryKey string) (tokenStr string, e error) {
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodES256, &Claims{
|
||||
Username: username,
|
||||
Nickname: nickname,
|
||||
ExtID: eid,
|
||||
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(primaryKey)); e != nil {
|
||||
panic(e)
|
||||
}
|
||||
tokenStr, e = token.SignedString(ecdsaKey)
|
||||
return
|
||||
}
|
||||
|
||||
func VerifyToken(tokenStr, publicKey string) (access bool, claims Claims, e error) {
|
||||
var ecdsaKeyPub *ecdsa.PublicKey
|
||||
if ecdsaKeyPub, e = jwt.ParseECPublicKeyFromPEM([]byte(publicKey)); e != nil {
|
||||
return
|
||||
}
|
||||
var token *jwt.Token
|
||||
if token, e = jwt.ParseWithClaims(tokenStr, &claims, func(token *jwt.Token) (interface{}, error) {
|
||||
return ecdsaKeyPub, nil
|
||||
}); e != nil {
|
||||
return
|
||||
}
|
||||
access = token.Valid
|
||||
return
|
||||
}
|
||||
|
||||
func JwtID() string {
|
||||
u4 := uuid.New()
|
||||
return strings.ReplaceAll(u4.String(), "-", "")
|
||||
}
|
||||
12
pkg/secure/jwt_test.go
Normal file
12
pkg/secure/jwt_test.go
Normal file
@ -0,0 +1,12 @@
|
||||
package secure
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestVerifyToken(t *testing.T) {
|
||||
ts := "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Inlhbmd0YW8iLCJuaWNrbmFtZSI6IuadqOeEmCIsImlzcyI6InpreHFncm91cC5jb20iLCJzdWIiOiJhZjBmNzM4OGM0MDk0MWQzYmU5NTdiYmExM2RkMzExYiIsImV4cCI6MTY4NDkxMjAwNCwibmJmIjoxNjg0ODI1NjA0LCJpYXQiOjE2ODQ4MjU2MDQsImp0aSI6IjkyNzIzMDM0NGE5MTQ0MTU4OTQyYWI4YmQ2MzkwMmQ2In0.58aFVo5FyTem4Fc2PZVBVEB-0DO2hhHuJ34ASGZQh1Cmd3peD5V5scWPdtx3wF3FAkXG_uE-o9smboGeuqscKQ"
|
||||
gotAccess, gotClaims, err := VerifyToken(ts, "")
|
||||
fmt.Printf("%v %v %v\n", gotAccess, gotClaims, err)
|
||||
}
|
||||
9
pkg/secure/password_test.go
Normal file
9
pkg/secure/password_test.go
Normal file
@ -0,0 +1,9 @@
|
||||
package secure
|
||||
|
||||
import "testing"
|
||||
|
||||
func Test_generatePasswd(t *testing.T) {
|
||||
for i := 0; i < 20; i++ {
|
||||
println(GeneratePasswd("advance", 16))
|
||||
}
|
||||
}
|
||||
71
pkg/secure/tool.go
Normal file
71
pkg/secure/tool.go
Normal file
@ -0,0 +1,71 @@
|
||||
package secure
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
randcrypto "crypto/rand"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
type PassLevel string
|
||||
|
||||
const (
|
||||
High PassLevel = "advance"
|
||||
Mid PassLevel = "mix"
|
||||
Low PassLevel = "char"
|
||||
Danger PassLevel = "num"
|
||||
|
||||
nUmStr = "0123456789"
|
||||
charStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
specStr = "+=-@#~,.[]()!%^*$"
|
||||
)
|
||||
|
||||
var (
|
||||
r = rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
)
|
||||
|
||||
func GeneratePasswd(level PassLevel, length int32) string {
|
||||
var passwd = make([]byte, length, length)
|
||||
var sourceStr string
|
||||
switch level {
|
||||
case Danger:
|
||||
sourceStr = nUmStr
|
||||
case Low:
|
||||
sourceStr = charStr
|
||||
case Mid:
|
||||
sourceStr = fmt.Sprintf("%s%s", nUmStr, charStr)
|
||||
case High:
|
||||
sourceStr = fmt.Sprintf("%s%s%s", nUmStr, charStr, specStr)
|
||||
default:
|
||||
sourceStr = fmt.Sprintf("%s%s", nUmStr, charStr)
|
||||
}
|
||||
for i := range passwd {
|
||||
index := r.Intn(len(sourceStr))
|
||||
passwd[i] = sourceStr[index]
|
||||
}
|
||||
return string(passwd)
|
||||
}
|
||||
|
||||
func GenerateECDSAKeyPem() (primaryKey, publicKey []byte, e error) {
|
||||
var (
|
||||
key *ecdsa.PrivateKey
|
||||
sec []byte
|
||||
pk []byte
|
||||
)
|
||||
if key, e = ecdsa.GenerateKey(elliptic.P256(), randcrypto.Reader); e != nil {
|
||||
return
|
||||
}
|
||||
if sec, e = x509.MarshalECPrivateKey(key); e != nil {
|
||||
return
|
||||
}
|
||||
if pk, e = x509.MarshalPKIXPublicKey(key.Public()); e != nil {
|
||||
return
|
||||
}
|
||||
primaryKey = pem.EncodeToMemory(&pem.Block{Type: "ECD PRIVATE KEY", Bytes: sec})
|
||||
publicKey = pem.EncodeToMemory(&pem.Block{Type: "ECD PUBLIC KEY", Bytes: pk})
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user