206 lines
4.7 KiB
Go
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()
|
|
}
|