Files
xlgo-core/middleware/auth.go
T
杭州明婳科技 2dfcbbbb22 init
2026-04-30 23:26:14 +08:00

212 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 (
"strings"
"github.com/EthanCodeCraft/xlgo-core/jwt"
"github.com/EthanCodeCraft/xlgo-core/response"
"github.com/gin-gonic/gin"
)
const (
// ContextKeyUserID 用户ID上下文键
ContextKeyUserID = "user_id"
// ContextKeyUsername 用户名上下文键
ContextKeyUsername = "username"
// ContextKeyRole 角色上下文键
ContextKeyRole = "role"
// ContextKeyUserType 用户类型上下文键
ContextKeyUserType = "user_type"
)
// AuthRequired JWT 认证中间件
func AuthRequired() gin.HandlerFunc {
return func(c *gin.Context) {
authHeader := c.GetHeader("Authorization")
if authHeader == "" {
response.Unauthorized(c, "请先登录")
c.Abort()
return
}
// 解析 Bearer Token
parts := strings.SplitN(authHeader, " ", 2)
if len(parts) != 2 || parts[0] != "Bearer" {
response.Unauthorized(c, "认证格式错误")
c.Abort()
return
}
tokenString := parts[1]
claims, err := jwt.ParseToken(tokenString)
if err != nil {
response.Unauthorized(c, "登录已过期,请重新登录")
c.Abort()
return
}
// 将用户信息存入上下文
c.Set(ContextKeyUserID, claims.UserID)
c.Set(ContextKeyUsername, claims.Username)
c.Set(ContextKeyRole, claims.Role)
c.Set(ContextKeyUserType, claims.UserType)
c.Next()
}
}
// AdminRequired 管理员权限中间件
func AdminRequired() gin.HandlerFunc {
return func(c *gin.Context) {
userType, exists := c.Get(ContextKeyUserType)
if !exists {
response.Unauthorized(c, "请先登录")
c.Abort()
return
}
// 安全的类型断言
ut, ok := userType.(string)
if !ok {
response.Unauthorized(c, "用户信息异常")
c.Abort()
return
}
if ut != "super_admin" && ut != "admin" {
response.Fail(c, "无权限访问")
c.Abort()
return
}
c.Next()
}
}
// SuperAdminRequired 超级管理员权限中间件
func SuperAdminRequired() gin.HandlerFunc {
return func(c *gin.Context) {
userType, exists := c.Get(ContextKeyUserType)
if !exists {
response.Unauthorized(c, "请先登录")
c.Abort()
return
}
// 安全的类型断言
ut, ok := userType.(string)
if !ok {
response.Unauthorized(c, "用户信息异常")
c.Abort()
return
}
if ut != "super_admin" {
response.Fail(c, "需要超级管理员权限")
c.Abort()
return
}
c.Next()
}
}
// StaffRequired 员工权限中间件
func StaffRequired() gin.HandlerFunc {
return func(c *gin.Context) {
userType, exists := c.Get(ContextKeyUserType)
if !exists {
response.Unauthorized(c, "请先登录")
c.Abort()
return
}
// 安全的类型断言
ut, ok := userType.(string)
if !ok {
response.Unauthorized(c, "用户信息异常")
c.Abort()
return
}
if ut != "staff" {
response.Fail(c, "无权限访问")
c.Abort()
return
}
c.Next()
}
}
// AnyUserRequired 任意用户权限中间件(允许 admin/super_admin/staff
func AnyUserRequired() gin.HandlerFunc {
return func(c *gin.Context) {
userType, exists := c.Get(ContextKeyUserType)
if !exists {
response.Unauthorized(c, "请先登录")
c.Abort()
return
}
// 安全的类型断言
ut, ok := userType.(string)
if !ok {
response.Unauthorized(c, "用户信息异常")
c.Abort()
return
}
// 允许所有内部用户类型
if ut != "super_admin" && ut != "admin" && ut != "staff" {
response.Fail(c, "无权限访问")
c.Abort()
return
}
c.Next()
}
}
// GetUserID 从上下文获取用户ID
func GetUserID(c *gin.Context) uint {
userID, exists := c.Get(ContextKeyUserID)
if !exists {
return 0
}
// 安全的类型断言
id, ok := userID.(uint)
if !ok {
return 0
}
return id
}
// GetUsername 从上下文获取用户名
func GetUsername(c *gin.Context) string {
username, exists := c.Get(ContextKeyUsername)
if !exists {
return ""
}
// 安全的类型断言
name, ok := username.(string)
if !ok {
return ""
}
return name
}
// GetUserType 从上下文获取用户类型
func GetUserType(c *gin.Context) string {
userType, exists := c.Get(ContextKeyUserType)
if !exists {
return ""
}
// 安全的类型断言
ut, ok := userType.(string)
if !ok {
return ""
}
return ut
}