| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- package middleware
- import (
- "app/commons/config"
- "app/commons/core/redisclient"
- "context"
- "errors"
- "fmt"
- "github.com/golang-jwt/jwt/v5"
- "strings"
- "time"
- )
- type Member struct {
- ID int64
- //Address string
- OpenId string
- Uid string
- }
- // Secret key used to sign the JWT token (In production, use environment variables to keep it secure)
- var jwtSecretByte = []byte("magic.node.secret.20251212")
- var jwtExpireDuration = int64(24) // in seconds
- var jwtIssuer = "issuer"
- var jwtConf *config.JWT
- func conf() *config.JWT {
- if jwtConf == nil {
- jwtConf = config.EnvConf().JWT
- }
- if jwtConf.SigningKey != "" {
- jwtSecretByte = []byte(jwtConf.SigningKey)
- }
- if jwtConf.ExpiresTime > 0 {
- jwtExpireDuration = jwtConf.ExpiresTime
- }
- if jwtConf.Issuer != "" {
- jwtIssuer = jwtConf.Issuer
- }
- //core.Log.Infof("Issuer:%s ExpiresTime:%dh SigningKey:%s", jwtIssuer, jwtExpireDuration, jwtSecretByte)
- return jwtConf
- }
- // MyClaims 定义了JWT中的自定义声明
- //
- // Address string `json:"address"`
- type MyClaims struct {
- UserID int64 `json:"userId"`
- OpenId string `json:"openId"`
- Uid string `json:"uid"`
- jwt.RegisteredClaims
- }
- // GenerateJWT 根据用户信息生成JWT
- func GenerateJWT(user Member) (string, error) {
- if jwtConf == nil {
- conf()
- }
- // 设置JWT的过期时间
- d := time.Duration(jwtExpireDuration) * time.Hour
- expirationTime := time.Now().Add(d)
- // 创建JWT的声明
- claims := MyClaims{
- UserID: user.ID,
- OpenId: user.OpenId,
- Uid: user.Uid,
- RegisteredClaims: jwt.RegisteredClaims{
- ID: fmt.Sprintf("%d", user.ID), // 设置ID
- ExpiresAt: jwt.NewNumericDate(expirationTime), // 设置过期时间
- Issuer: jwtIssuer, // 设置签发者
- },
- }
- // 使用HS256算法签署JWT
- token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
- // 生成并返回签名后的JWT字符串
- tokenString, err := token.SignedString(jwtSecretByte)
- if err != nil {
- return "", err
- }
- return tokenString, nil
- }
- // ParseJWT 解析和验证JWT
- func ParseJWT(tokenString string) (*MyClaims, error) {
- if jwtConf == nil {
- conf()
- }
- // 定义一个空的声明对象
- claims := &MyClaims{}
- // 去掉 "Bearer " 部分
- tokenString = strings.TrimPrefix(tokenString, "Bearer ")
- // 解析JWT
- token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
- // 验证签名算法
- if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
- return nil, errors.New("unexpected signing method")
- }
- return jwtSecretByte, nil
- })
- if err != nil || !token.Valid {
- return nil, errors.New("invalid token")
- }
- return claims, nil
- }
- // SetUserCurrentToken 设置用户当前有效token
- func SetUserCurrentToken(userID int64, tokenString string, expiration time.Duration) error {
- tokenString = strings.TrimPrefix(tokenString, "Bearer ")
- key := fmt.Sprintf("user_current_token:%d", userID)
- return redisclient.DefaultClient().Set(context.Background(), key, tokenString, expiration).Err()
- }
- // IsCurrentValidToken 检查token是否为用户当前有效token
- func IsCurrentValidToken(userID int64, tokenString string) bool {
- tokenString = strings.TrimPrefix(tokenString, "Bearer ")
- key := fmt.Sprintf("user_current_token:%d", userID)
- currentToken, err := redisclient.DefaultClient().Get(context.Background(), key).Result()
- if err != nil {
- return false // 如果获取失败,说明没有有效token或已过期
- }
- return currentToken == tokenString // 检查是否为当前有效token
- }
|