Files
ppgo_job/middleware/auth.go
T
2026-07-10 11:28:16 +08:00

206 lines
4.7 KiB
Go

package middleware
import (
"ppgo_job/dao"
"ppgo_job/libs"
"ppgo_job/model/entity"
"strings"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/util/gconv"
)
// Auth 认证中间件 — 支持 Cookie 和 JWT 双认证
func Auth(r *ghttp.Request) {
// 尝试 Cookie 认证(兼容旧模板)
if tryCookieAuth(r) {
r.Middleware.Next()
return
}
// 尝试 JWT 认证(新前端)
if tryJWTAuth(r) {
r.Middleware.Next()
return
}
// 都失败
redirectToLogin(r)
}
// tryJWTAuth 尝试 JWT 认证
func tryJWTAuth(r *ghttp.Request) bool {
authHeader := r.Header.Get("Authorization")
if authHeader == "" {
// 也尝试从 query 参数读取 token
authHeader = r.Get("token", "").String()
if authHeader == "" {
return false
}
}
// 去除 Bearer 前缀
token := strings.TrimPrefix(authHeader, "Bearer ")
if token == authHeader {
// 没有 Bearer 前缀,去掉也行
}
claims, err := libs.ParseJWT(token)
if err != nil {
return false
}
// 查询用户是否存在且未被禁用
admin, err := dao.Admin.GetById(r.GetCtx(), claims.UserId)
if err != nil || admin == nil || admin.Status != 1 {
return false
}
// 注入用户信息
r.SetCtxVar("userId", admin.Id)
r.SetCtxVar("loginUserId", admin.Id)
r.SetCtxVar("loginUserName", admin.RealName)
r.SetCtxVar("user", admin)
// 加载权限
loadPermissions(r, admin)
return true
}
// tryCookieAuth 尝试 Cookie 认证(兼容旧模板)
func tryCookieAuth(r *ghttp.Request) bool {
authCookie := r.Cookie.Get("auth")
if authCookie == nil {
return false
}
authStr := authCookie.String()
parts := strings.Split(authStr, "|")
if len(parts) != 2 {
return false
}
userId := gconv.Int(parts[0])
hash := parts[1]
if userId < 1 || hash == "" {
return false
}
// 查询用户
admin, err := dao.Admin.GetById(r.GetCtx(), userId)
if err != nil || admin == nil || admin.Status != 1 {
return false
}
// 验证 hash
clientIp := r.GetClientIp()
expectedHash := libs.Sha256Hex([]byte(admin.Salt + "|" + clientIp + "|" + admin.Password))
if hash != expectedHash {
return false
}
// 注入用户信息
r.SetCtxVar("userId", admin.Id)
r.SetCtxVar("loginUserId", admin.Id)
r.SetCtxVar("loginUserName", admin.RealName)
r.SetCtxVar("user", admin)
// 加载权限
loadPermissions(r, admin)
return true
}
// AuthCheck 权限检查中间件
func AuthCheck(r *ghttp.Request) {
userId := r.GetCtxVar("userId", 0).Int()
if userId == 0 {
redirectToLogin(r)
return
}
r.Middleware.Next()
}
// loadPermissions 加载权限和菜单
func loadPermissions(r *ghttp.Request, admin *entity.Admin) {
ctx := r.GetCtx()
// 从角色的权限关联获取可访问的URL
var allowUrls []string
// 侧边栏菜单
authList, _ := dao.Auth.GetList(ctx, "status", 1)
menu1 := make([]g.Map, 0)
menu2 := make([]g.Map, 0)
for _, v := range authList {
if v.Pid == 0 && v.IsShow == 1 {
allowUrls = append(allowUrls, v.AuthUrl)
menu1 = append(menu1, g.Map{
"Id": v.Id,
"Sort": v.Sort,
"AuthName": v.AuthName,
"AuthUrl": v.AuthUrl,
"Icon": v.Icon,
"Pid": v.Pid,
})
} else if v.Pid != 0 && v.IsShow == 1 {
allowUrls = append(allowUrls, v.AuthUrl)
menu2 = append(menu2, g.Map{
"Id": v.Id,
"Sort": v.Sort,
"AuthName": v.AuthName,
"AuthUrl": v.AuthUrl,
"Icon": v.Icon,
"Pid": v.Pid,
})
}
}
r.SetCtxVar("SideMenu1", menu1)
r.SetCtxVar("SideMenu2", menu2)
r.SetCtxVar("allowUrl", strings.Join(allowUrls, ","))
// 数据权限
roleIds := admin.RoleIds
if roleIds == "" || roleIds == "0" || admin.Id == 1 {
r.SetCtxVar("serverGroups", "")
r.SetCtxVar("taskGroups", "")
return
}
// 非超级管理员,按角色限制数据范围
roleIdArr := strings.Split(roleIds, ",")
allServerGroups := make([]string, 0)
allTaskGroups := make([]string, 0)
for _, rid := range roleIdArr {
if id := gconv.Int(rid); id > 0 {
role, _ := dao.Role.GetById(ctx, id)
if role != nil {
if role.ServerGroupIds != "" {
allServerGroups = append(allServerGroups, role.ServerGroupIds)
}
if role.TaskGroupIds != "" {
allTaskGroups = append(allTaskGroups, role.TaskGroupIds)
}
}
}
}
r.SetCtxVar("serverGroups", strings.Join(allServerGroups, ","))
r.SetCtxVar("taskGroups", strings.Join(allTaskGroups, ","))
}
func redirectToLogin(r *ghttp.Request) {
if r.IsAjaxRequest() {
r.Response.WriteJson(g.Map{"status": -1, "message": "请先登录"})
} else {
// API 请求也返回 JSON
if strings.HasPrefix(r.URL.Path, "/api/") {
r.Response.WriteJson(g.Map{"code": 401, "message": "请先登录"})
} else {
r.Response.RedirectTo("/")
}
}
r.Exit()
}