低空智控平台 后端go
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

75 lines
2.1 KiB

package middleware
import (
"net/http"
"slices"
"strconv"
"strings"
"github.com/gin-gonic/gin"
"laic-backend/cache"
"laic-backend/common"
"laic-backend/token"
)
// AuthMiddleware 鉴权中间件:解析 JWT + Redis 存证校验 + 注入上下文
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
tokenString := c.GetHeader("Authorization")
if tokenString == "" {
common.FailWithBusiErrorWithHttpStatus(c, http.StatusUnauthorized, common.ErrUnauthorized)
return
}
tokenString = strings.TrimPrefix(tokenString, "Bearer ")
if tokenString == "" {
common.FailWithBusiErrorWithHttpStatus(c, http.StatusUnauthorized, common.ErrUnauthorized)
return
}
claims, err := token.ParseToken(tokenString)
if err != nil {
common.FailWithBusiErrorWithHttpStatus(c, http.StatusUnauthorized, common.ErrToken)
return
}
// Redis 存证校验:登出会删除该 key,从而让已签发 token 失效
storeKey := cache.UserTokenKeyOf(claims.UserID, token.GenerateShortID(tokenString))
if !common.HasKey(storeKey) {
common.FailWithBusiErrorWithHttpStatus(c, http.StatusUnauthorized, common.SignOutToken)
return
}
roles := claims.Roles
if roles == nil {
roles = []string{}
}
isAdmin := slices.Contains(roles, common.RoleAdmin)
c.Set("user_id", claims.UserID)
c.Set("username", claims.Username)
c.Set("roles", roles)
c.Set("is_admin", isAdmin)
// Casbin 权限校验(admin 与普通用户均按 p/g 策略校验,admin 仅限平台管理职能)
if common.CasbinEnforcer != nil {
ok, err := common.CasbinEnforcer.Enforce(strconv.FormatInt(claims.UserID, 10), c.Request.URL.Path, c.Request.Method)
if err != nil || !ok {
common.FailWithBusiErrorWithHttpStatus(c, http.StatusForbidden, common.ErrForbidden)
c.Abort()
return
}
}
c.Next()
}
}
// AdminMiddleware 仅管理员可访问
func AdminMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
if !c.GetBool("is_admin") {
common.FailWithBusiErrorWithHttpStatus(c, http.StatusForbidden, common.ErrForbidden)
return
}
c.Next()
}
}