Skip to content

Commit

Permalink
feat!: Add JWT
Browse files Browse the repository at this point in the history
- `RUSTDESK_API_JWT_KEY`如果设置,将会启用JWT,token自动续期功能将失效
- 此功能是为了server端校验token的合法性
  • Loading branch information
lejianwen committed Jan 15, 2025
1 parent 3c60846 commit f41b9d5
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 22 deletions.
4 changes: 3 additions & 1 deletion cmd/apimain.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"Gwen/global"
"Gwen/http"
"Gwen/lib/cache"
"Gwen/lib/jwt"
"Gwen/lib/lock"
"Gwen/lib/logger"
"Gwen/lib/orm"
Expand All @@ -17,6 +18,7 @@ import (
"github.com/spf13/cobra"
"os"
"strconv"
"time"
)

// @title 管理系统API
Expand Down Expand Up @@ -163,7 +165,7 @@ func InitGlobal() {

//jwt
//fmt.Println(global.Config.Jwt.PrivateKey)
//global.Jwt = jwt.NewJwt(global.Config.Jwt.PrivateKey, global.Config.Jwt.ExpireDuration*time.Second)
global.Jwt = jwt.NewJwt(global.Config.Jwt.Key, global.Config.Jwt.ExpireDuration*time.Second)

//locker
global.Lock = lock.NewLocal()
Expand Down
7 changes: 4 additions & 3 deletions conf/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ logger:
proxy:
enable: false
host: "http://127.0.0.1:1080"
jwt:
key: ""
expire-duration: 360000
redis:
addr: "127.0.0.1:6379"
password: ""
Expand All @@ -53,6 +56,4 @@ oss:
callback-url: ""
expire-time: 30
max-byte: 10240
jwt:
private-key: "./conf/jwt_pri.pem"
expire-duration: 360000

Empty file removed conf/jwt_pri.pem
Empty file.
2 changes: 1 addition & 1 deletion config/jwt.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ package config
import "time"

type Jwt struct {
PrivateKey string `mapstructure:"private-key"`
Key string `mapstructure:"key"`
ExpireDuration time.Duration `mapstructure:"expire-duration"`
}
17 changes: 16 additions & 1 deletion http/middleware/rustauth.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package middleware

import (
"Gwen/global"
"Gwen/service"
"github.com/gin-gonic/gin"
)
Expand All @@ -27,7 +28,21 @@ func RustAuth() gin.HandlerFunc {
//提取token,格式是Bearer {token}
//这里只是简单的提取
token = token[7:]

//验证token

//检查是否设置了jwt key
if global.Config.Jwt.Key != "" {
uid, _ := service.AllService.UserService.VerifyJWT(token)
if uid == 0 {
c.JSON(401, gin.H{
"error": "Unauthorized",
})
c.Abort()
return
}
}

user, ut := service.AllService.UserService.InfoByAccessToken(token)
if user.Id == 0 {
c.JSON(401, gin.H{
Expand All @@ -38,7 +53,7 @@ func RustAuth() gin.HandlerFunc {
}
if !service.AllService.UserService.CheckUserEnable(user) {
c.JSON(401, gin.H{
"error": "账号已被禁用",
"error": "Unauthorized",
})
c.Abort()
return
Expand Down
24 changes: 8 additions & 16 deletions lib/jwt/jwt.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package jwt

import (
"crypto/rsa"
"fmt"
"github.com/golang-jwt/jwt/v5"
"os"
"time"
)

type Jwt struct {
privateKey *rsa.PrivateKey
Key []byte
TokenExpireDuration time.Duration
}

Expand All @@ -17,39 +16,32 @@ type UserClaims struct {
jwt.RegisteredClaims
}

func NewJwt(privateKeyFile string, tokenExpireDuration time.Duration) *Jwt {
privateKeyContent, err := os.ReadFile(privateKeyFile)
if err != nil {
panic(err)
}
privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(privateKeyContent)
if err != nil {
panic(err)
}
func NewJwt(key string, tokenExpireDuration time.Duration) *Jwt {
return &Jwt{
privateKey: privateKey,
Key: []byte(key),
TokenExpireDuration: tokenExpireDuration,
}
}

func (s *Jwt) GenerateToken(userId uint) string {
t := jwt.NewWithClaims(jwt.SigningMethodRS256,
t := jwt.NewWithClaims(jwt.SigningMethodHS256,
UserClaims{
UserId: userId,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(s.TokenExpireDuration)),
},
})
token, err := t.SignedString(s.privateKey)
token, err := t.SignedString(s.Key)
if err != nil {
fmt.Println(err)
return ""
}
return token
}

func (s *Jwt) ParseToken(tokenString string) (uint, error) {
token, err := jwt.ParseWithClaims(tokenString, &UserClaims{}, func(token *jwt.Token) (interface{}, error) {
return s.privateKey.Public(), nil
return s.Key, nil
})
if err != nil {
return 0, err
Expand Down
7 changes: 7 additions & 0 deletions service/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ func (us *UserService) InfoByAccessToken(token string) (*model.User, *model.User

// GenerateToken 生成token
func (us *UserService) GenerateToken(u *model.User) string {
if global.Config.Jwt.Key != "" {
return global.Jwt.GenerateToken(u.Id)
}
return utils.Md5(u.Username + time.Now().String())
}

Expand Down Expand Up @@ -461,3 +464,7 @@ func (us *UserService) AutoRefreshAccessToken(ut *model.UserToken) {
func (us *UserService) BatchDeleteUserToken(ids []uint) error {
return global.DB.Where("id in ?", ids).Delete(&model.UserToken{}).Error
}

func (us *UserService) VerifyJWT(token string) (uint, error) {
return global.Jwt.ParseToken(token)
}

0 comments on commit f41b9d5

Please sign in to comment.