添加jwt鉴权中间件

This commit is contained in:
2025-08-28 17:44:20 +08:00
parent 0a3be6cf9e
commit 327f02630a
4 changed files with 95 additions and 8 deletions

View File

@@ -0,0 +1,81 @@
package middleware
import (
"errors"
"gin-admin/internal/core/config"
"gin-admin/pkg/auth"
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt/v5"
"net/http"
"regexp"
"strings"
systemmodel "gin-admin/internal/model/system"
)
// @Author: yv1ing
// @Author: me@yvling.cn
// @Date: 2025/8/28 17:31
// @Desc: 鉴权中间件
func extractBearerToken(c *gin.Context) string {
authorization := c.GetHeader("Authorization")
if authorization == "" {
return ""
}
parts := strings.SplitN(authorization, " ", 2)
if len(parts) != 2 || !strings.EqualFold(parts[0], "Bearer") || parts[1] == "" {
return ""
}
return parts[1]
}
func JwtMiddleware(whitelist []string) gin.HandlerFunc {
var whitelistRegex []*regexp.Regexp
for _, pattern := range whitelist {
re, err := regexp.Compile(pattern)
if err == nil {
whitelistRegex = append(whitelistRegex, re)
}
}
return func(c *gin.Context) {
path := c.Request.URL.Path
for _, re := range whitelistRegex {
if re.MatchString(path) {
c.Next()
return
}
}
tokenStr := extractBearerToken(c)
if tokenStr == "" {
c.AbortWithStatusJSON(http.StatusUnauthorized, systemmodel.Response{
Code: http.StatusUnauthorized,
Info: "请求头Authorization非法或缺失",
})
return
}
claims, err := auth.ParseAccessToken(tokenStr, config.Config.SecretKey)
if err != nil {
if errors.Is(err, jwt.ErrTokenExpired) {
c.AbortWithStatusJSON(http.StatusUnauthorized, systemmodel.Response{
Code: http.StatusUnauthorized,
Info: "Token已过期",
})
} else {
c.AbortWithStatusJSON(http.StatusUnauthorized, systemmodel.Response{
Code: http.StatusUnauthorized,
Info: "Token不合法",
})
}
return
}
c.Set("UID", claims.ID)
c.Next()
}
}

View File

@@ -1,6 +1,7 @@
package router
import (
"gin-admin/internal/middleware"
"github.com/gin-gonic/gin"
systemapi "gin-admin/internal/api/system"
@@ -11,7 +12,13 @@ import (
// @Date: 2025/8/28 16:17
// @Desc: 路由注册入口
var whitelist = []string{
`^/api/sys/login$`,
}
func SetupRoutes(eng *gin.Engine) {
eng.Use(middleware.JwtMiddleware(whitelist))
api := eng.Group("/api")
/* 系统内置接口 */

View File

@@ -2,9 +2,9 @@ package system
import (
"errors"
"gin-admin/internal/auth"
"gin-admin/internal/core/config"
"gin-admin/internal/repository"
"gin-admin/pkg/auth"
"gin-admin/pkg/encrypt"
"gorm.io/gorm"
@@ -31,7 +31,7 @@ func SysUserLogin(username, password string) (string, error) {
return "", errors.New("用户已被禁用")
}
jwtToken, err := auth.CreateAccessToken(user.ID, user.Username, 3600)
jwtToken, err := auth.CreateAccessToken(user.ID, user.Username, config.Config.SecretKey)
if err != nil {
return "", errors.New("系统内部错误")
}

View File

@@ -3,7 +3,6 @@ package auth
import (
"errors"
"fmt"
"gin-admin/internal/core/config"
"github.com/golang-jwt/jwt/v5"
"time"
)
@@ -19,8 +18,8 @@ type AccessClaims struct {
jwt.RegisteredClaims
}
func CreateAccessToken(ID uint, username string, ttl time.Duration) (string, error) {
jwtSecret := []byte(config.Config.SecretKey)
func CreateAccessToken(ID uint, username string, secretKey string) (string, error) {
jwtSecret := []byte(secretKey)
claims := AccessClaims{
ID: ID,
@@ -28,7 +27,7 @@ func CreateAccessToken(ID uint, username string, ttl time.Duration) (string, err
RegisteredClaims: jwt.RegisteredClaims{
Subject: "gin-admin",
IssuedAt: jwt.NewNumericDate(time.Now()),
ExpiresAt: jwt.NewNumericDate(time.Now().Add(ttl)),
ExpiresAt: jwt.NewNumericDate(time.Now().Add(12 * time.Hour)),
ID: fmt.Sprintf("%d-%d", ID, time.Now().UnixNano()),
},
}
@@ -37,8 +36,8 @@ func CreateAccessToken(ID uint, username string, ttl time.Duration) (string, err
return token.SignedString(jwtSecret)
}
func ParseAccessToken(tokenStr string) (*AccessClaims, error) {
jwtSecret := []byte(config.Config.SecretKey)
func ParseAccessToken(tokenStr, secretKey string) (*AccessClaims, error) {
jwtSecret := []byte(secretKey)
token, err := jwt.ParseWithClaims(tokenStr, &AccessClaims{}, func(token *jwt.Token) (interface{}, error) {
return jwtSecret, nil
})