101 lines
2.5 KiB
Go
101 lines
2.5 KiB
Go
package utils
|
|
|
|
import (
|
|
"crypto/hmac"
|
|
"crypto/md5"
|
|
"crypto/rand"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"errors"
|
|
"time"
|
|
|
|
"github.com/golang-jwt/jwt/v5"
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
var jwtSecret = "please-change-this-secret-key"
|
|
var jwtExpire = 7 * time.Hour
|
|
|
|
// InitJWT 初始化JWT参数
|
|
func InitJWT(secret, expire string) {
|
|
if secret != "" {
|
|
jwtSecret = secret
|
|
}
|
|
if d, err := time.ParseDuration(expire); err == nil && d > 0 {
|
|
jwtExpire = d
|
|
}
|
|
}
|
|
|
|
// JWTClaims 自定义Claims
|
|
type JWTClaims struct {
|
|
UserID uint `json:"user_id"`
|
|
Username string `json:"username"`
|
|
RoleCode string `json:"role_code"`
|
|
jwt.RegisteredClaims
|
|
}
|
|
|
|
// GenerateToken 生成JWT Token
|
|
func GenerateToken(userID uint, username, roleCode string) (string, error) {
|
|
claims := JWTClaims{
|
|
UserID: userID,
|
|
Username: username,
|
|
RoleCode: roleCode,
|
|
RegisteredClaims: jwt.RegisteredClaims{
|
|
ExpiresAt: jwt.NewNumericDate(time.Now().Add(jwtExpire)),
|
|
IssuedAt: jwt.NewNumericDate(time.Now()),
|
|
Issuer: "filestoragesystem",
|
|
},
|
|
}
|
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
|
return token.SignedString([]byte(jwtSecret))
|
|
}
|
|
|
|
// ParseToken 解析并校验JWT Token
|
|
func ParseToken(tokenStr string) (*JWTClaims, error) {
|
|
token, err := jwt.ParseWithClaims(tokenStr, &JWTClaims{}, func(t *jwt.Token) (interface{}, error) {
|
|
if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
|
|
return nil, errors.New("非法的签名算法")
|
|
}
|
|
return []byte(jwtSecret), nil
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if claims, ok := token.Claims.(*JWTClaims); ok && token.Valid {
|
|
return claims, nil
|
|
}
|
|
return nil, errors.New("无效的Token")
|
|
}
|
|
|
|
// HashPassword bcrypt加密密码
|
|
func HashPassword(password string) (string, error) {
|
|
bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
|
return string(bytes), err
|
|
}
|
|
|
|
// CheckPassword 校验密码
|
|
func CheckPassword(hash, password string) bool {
|
|
return bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) == nil
|
|
}
|
|
|
|
// MD5 计算字节串的MD5
|
|
func MD5(data []byte) string {
|
|
h := md5.New()
|
|
h.Write(data)
|
|
return hex.EncodeToString(h.Sum(nil))
|
|
}
|
|
|
|
// RandomKey 生成指定长度的随机hex字符串
|
|
func RandomKey(n int) string {
|
|
b := make([]byte, (n+1)/2)
|
|
_, _ = rand.Read(b)
|
|
return hex.EncodeToString(b)[:n]
|
|
}
|
|
|
|
// HMACSHA256 计算HMAC-SHA256签名(hex编码)
|
|
func HMACSHA256(secret, message string) string {
|
|
mac := hmac.New(sha256.New, []byte(secret))
|
|
mac.Write([]byte(message))
|
|
return hex.EncodeToString(mac.Sum(nil))
|
|
}
|