Просмотр исходного кода

feat!: Add JWT

- `RUSTDESK_API_JWT_KEY`如果设置,将会启用JWT,token自动续期功能将失效
- 此功能是为了server端校验token的合法性
lejianwen 1 год назад
Родитель
Сommit
f41b9d5887
7 измененных файлов с 39 добавлено и 22 удалено
  1. 3 1
      cmd/apimain.go
  2. 4 3
      conf/config.yaml
  3. 0 0
      conf/jwt_pri.pem
  4. 1 1
      config/jwt.go
  5. 16 1
      http/middleware/rustauth.go
  6. 8 16
      lib/jwt/jwt.go
  7. 7 0
      service/user.go

+ 3 - 1
cmd/apimain.go

@@ -5,6 +5,7 @@ import (
5 5
 	"Gwen/global"
6 6
 	"Gwen/http"
7 7
 	"Gwen/lib/cache"
8
+	"Gwen/lib/jwt"
8 9
 	"Gwen/lib/lock"
9 10
 	"Gwen/lib/logger"
10 11
 	"Gwen/lib/orm"
@@ -17,6 +18,7 @@ import (
17 18
 	"github.com/spf13/cobra"
18 19
 	"os"
19 20
 	"strconv"
21
+	"time"
20 22
 )
21 23
 
22 24
 // @title 管理系统API
@@ -163,7 +165,7 @@ func InitGlobal() {
163 165
 
164 166
 	//jwt
165 167
 	//fmt.Println(global.Config.Jwt.PrivateKey)
166
-	//global.Jwt = jwt.NewJwt(global.Config.Jwt.PrivateKey, global.Config.Jwt.ExpireDuration*time.Second)
168
+	global.Jwt = jwt.NewJwt(global.Config.Jwt.Key, global.Config.Jwt.ExpireDuration*time.Second)
167 169
 
168 170
 	//locker
169 171
 	global.Lock = lock.NewLocal()

+ 4 - 3
conf/config.yaml

@@ -36,6 +36,9 @@ logger:
36 36
 proxy:
37 37
   enable: false
38 38
   host: "http://127.0.0.1:1080"
39
+jwt:
40
+  key: ""
41
+  expire-duration: 360000
39 42
 redis:
40 43
   addr: "127.0.0.1:6379"
41 44
   password: ""
@@ -53,6 +56,4 @@ oss:
53 56
   callback-url: ""
54 57
   expire-time: 30
55 58
   max-byte: 10240
56
-jwt:
57
-  private-key: "./conf/jwt_pri.pem"
58
-  expire-duration: 360000
59
+

+ 0 - 0
conf/jwt_pri.pem


+ 1 - 1
config/jwt.go

@@ -3,6 +3,6 @@ package config
3 3
 import "time"
4 4
 
5 5
 type Jwt struct {
6
-	PrivateKey     string        `mapstructure:"private-key"`
6
+	Key            string        `mapstructure:"key"`
7 7
 	ExpireDuration time.Duration `mapstructure:"expire-duration"`
8 8
 }

+ 16 - 1
http/middleware/rustauth.go

@@ -1,6 +1,7 @@
1 1
 package middleware
2 2
 
3 3
 import (
4
+	"Gwen/global"
4 5
 	"Gwen/service"
5 6
 	"github.com/gin-gonic/gin"
6 7
 )
@@ -27,7 +28,21 @@ func RustAuth() gin.HandlerFunc {
27 28
 		//提取token,格式是Bearer {token}
28 29
 		//这里只是简单的提取
29 30
 		token = token[7:]
31
+
30 32
 		//验证token
33
+
34
+		//检查是否设置了jwt key
35
+		if global.Config.Jwt.Key != "" {
36
+			uid, _ := service.AllService.UserService.VerifyJWT(token)
37
+			if uid == 0 {
38
+				c.JSON(401, gin.H{
39
+					"error": "Unauthorized",
40
+				})
41
+				c.Abort()
42
+				return
43
+			}
44
+		}
45
+
31 46
 		user, ut := service.AllService.UserService.InfoByAccessToken(token)
32 47
 		if user.Id == 0 {
33 48
 			c.JSON(401, gin.H{
@@ -38,7 +53,7 @@ func RustAuth() gin.HandlerFunc {
38 53
 		}
39 54
 		if !service.AllService.UserService.CheckUserEnable(user) {
40 55
 			c.JSON(401, gin.H{
41
-				"error": "账号已被禁用",
56
+				"error": "Unauthorized",
42 57
 			})
43 58
 			c.Abort()
44 59
 			return

+ 8 - 16
lib/jwt/jwt.go

@@ -1,14 +1,13 @@
1 1
 package jwt
2 2
 
3 3
 import (
4
-	"crypto/rsa"
4
+	"fmt"
5 5
 	"github.com/golang-jwt/jwt/v5"
6
-	"os"
7 6
 	"time"
8 7
 )
9 8
 
10 9
 type Jwt struct {
11
-	privateKey          *rsa.PrivateKey
10
+	Key                 []byte
12 11
 	TokenExpireDuration time.Duration
13 12
 }
14 13
 
@@ -17,31 +16,24 @@ type UserClaims struct {
17 16
 	jwt.RegisteredClaims
18 17
 }
19 18
 
20
-func NewJwt(privateKeyFile string, tokenExpireDuration time.Duration) *Jwt {
21
-	privateKeyContent, err := os.ReadFile(privateKeyFile)
22
-	if err != nil {
23
-		panic(err)
24
-	}
25
-	privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(privateKeyContent)
26
-	if err != nil {
27
-		panic(err)
28
-	}
19
+func NewJwt(key string, tokenExpireDuration time.Duration) *Jwt {
29 20
 	return &Jwt{
30
-		privateKey:          privateKey,
21
+		Key:                 []byte(key),
31 22
 		TokenExpireDuration: tokenExpireDuration,
32 23
 	}
33 24
 }
34 25
 
35 26
 func (s *Jwt) GenerateToken(userId uint) string {
36
-	t := jwt.NewWithClaims(jwt.SigningMethodRS256,
27
+	t := jwt.NewWithClaims(jwt.SigningMethodHS256,
37 28
 		UserClaims{
38 29
 			UserId: userId,
39 30
 			RegisteredClaims: jwt.RegisteredClaims{
40 31
 				ExpiresAt: jwt.NewNumericDate(time.Now().Add(s.TokenExpireDuration)),
41 32
 			},
42 33
 		})
43
-	token, err := t.SignedString(s.privateKey)
34
+	token, err := t.SignedString(s.Key)
44 35
 	if err != nil {
36
+		fmt.Println(err)
45 37
 		return ""
46 38
 	}
47 39
 	return token
@@ -49,7 +41,7 @@ func (s *Jwt) GenerateToken(userId uint) string {
49 41
 
50 42
 func (s *Jwt) ParseToken(tokenString string) (uint, error) {
51 43
 	token, err := jwt.ParseWithClaims(tokenString, &UserClaims{}, func(token *jwt.Token) (interface{}, error) {
52
-		return s.privateKey.Public(), nil
44
+		return s.Key, nil
53 45
 	})
54 46
 	if err != nil {
55 47
 		return 0, err

+ 7 - 0
service/user.go

@@ -68,6 +68,9 @@ func (us *UserService) InfoByAccessToken(token string) (*model.User, *model.User
68 68
 
69 69
 // GenerateToken 生成token
70 70
 func (us *UserService) GenerateToken(u *model.User) string {
71
+	if global.Config.Jwt.Key != "" {
72
+		return global.Jwt.GenerateToken(u.Id)
73
+	}
71 74
 	return utils.Md5(u.Username + time.Now().String())
72 75
 }
73 76
 
@@ -461,3 +464,7 @@ func (us *UserService) AutoRefreshAccessToken(ut *model.UserToken) {
461 464
 func (us *UserService) BatchDeleteUserToken(ids []uint) error {
462 465
 	return global.DB.Where("id in ?", ids).Delete(&model.UserToken{}).Error
463 466
 }
467
+
468
+func (us *UserService) VerifyJWT(token string) (uint, error) {
469
+	return global.Jwt.ParseToken(token)
470
+}