Files
bl/modules/base/middleware/authority.go
昔念 b049e129c5
All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful
1
2026-02-03 22:44:13 +08:00

171 lines
4.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package middleware
import (
"blazing/cool"
"blazing/modules/base/config"
"github.com/gogf/gf/v2/container/garray"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gconv"
"github.com/golang-jwt/jwt/v4"
)
// 本类接口无需权限验证
func BaseAuthorityMiddlewareOpen(r *ghttp.Request) {
r.SetCtxVar("AuthOpen", true)
r.Middleware.Next()
}
// 本类接口无需权限验证,只需登录验证
func BaseAuthorityMiddlewareComm(r *ghttp.Request) {
r.SetCtxVar("AuthComm", true)
r.Middleware.Next()
}
// 其余接口需登录验证同时需要权限验证
func BaseAuthorityMiddleware(r *ghttp.Request) {
// g.Dump(r)
// g.Dump(r.GetHeader("Authorization"))
var (
statusCode = 200
ctx = r.GetCtx()
)
url := r.URL.String()
// 无需登录验证
AuthOpen := r.GetCtxVar("AuthOpen", false)
if AuthOpen.Bool() {
r.Middleware.Next()
return
}
tokenString := r.GetHeader("Authorization")
if tokenString == "" {
tokenString = r.URL.Query().Get("Authorization")
}
token, err := jwt.ParseWithClaims(tokenString, &cool.Claims{}, func(token *jwt.Token) (interface{}, error) {
return []byte(config.Config.Jwt.Secret), nil
})
if err != nil {
statusCode = 401
r.Response.WriteStatusExit(statusCode, g.Map{
"code": 1001,
"message": "登陆失效~",
})
}
if !token.Valid {
statusCode = 401
r.Response.WriteStatusExit(statusCode, g.Map{
"code": 1001,
"message": "登陆失效~",
})
}
admin := token.Claims.(*cool.Claims)
// 将用户信息放入上下文
r.SetCtxVar("admin", admin)
cachetoken, _ := cool.CacheManager.Get(ctx, "admin:token:"+gconv.String(admin.UserId))
rtoken := cachetoken.String()
// 超管拥有所有权限
if admin.UserId == 10001 && !admin.IsRefresh {
if tokenString != rtoken && config.Config.Jwt.Sso {
statusCode = 401
r.Response.WriteStatusExit(statusCode, g.Map{
"code": 1001,
"message": "登陆失效~",
})
} else {
r.Middleware.Next()
return
}
}
// 只验证登录不验证权限的接口
AuthComm := r.GetCtxVar("AuthComm", false)
if AuthComm.Bool() {
r.Middleware.Next()
return
}
// 如果传的token是refreshToken则校验失败
if admin.IsRefresh {
statusCode = 401
r.Response.WriteStatusExit(statusCode, g.Map{
"code": 1001,
"message": "登陆失效~",
})
}
// 判断密码版本是否正确
passwordV, _ := cool.CacheManager.Get(ctx, "admin:passwordVersion:"+gconv.String(admin.UserId))
if passwordV.Int32() != *admin.PasswordVersion {
statusCode = 401
r.Response.WriteStatusExit(statusCode, g.Map{
"code": 1001,
"message": "密码过期,登陆失效~",
})
}
// 如果rtoken为空
if rtoken == "" {
statusCode = 401
r.Response.WriteStatusExit(statusCode, g.Map{
"code": 1001,
"message": "登陆失效~",
})
}
// 如果rtoken不等于token 且 sso 未开启
if tokenString != rtoken && !config.Config.Jwt.Sso {
statusCode = 401
r.Response.WriteStatusExit(statusCode, g.Map{
"code": 1001,
"message": "登陆失效~",
})
}
// 从缓存获取perms
permsCache, _ := cool.CacheManager.Get(ctx, "admin:perms:"+gconv.String(admin.UserId))
// 转换为数组
permsVar := permsCache.Strings()
// 转换为garray
perms := garray.NewStrArrayFrom(permsVar)
// 如果perms为空
if perms.Len() == 0 {
statusCode = 403
r.Response.WriteStatusExit(statusCode, g.Map{
"code": 1001,
"message": "登录失效或无权限访问~",
})
}
// 去除url后面的参数使用字符串分割方法若长度等于2则说明有参数则我们将改写url值进行权限比对
parts := gstr.Split(url, "?")
if len(parts) == 2 {
url = parts[0]
}
//url 转换为数组
urls := gstr.Split(url, "/")
// 去除第一个空字符串和admin
urls = urls[2:]
// 以冒号连接成新字符串url
url = gstr.Join(urls, ":")
// 如果perms中不包含url 则无权限
if !perms.ContainsI(url) {
statusCode = 403
r.Response.WriteStatusExit(statusCode, g.Map{
"code": 1001,
"message": "登录失效或无权限访问~",
})
}
// 上面写逻辑
r.Middleware.Next()
}