material_manage_system/internal/middleware/auth.go
2026-09-15 16:08:18 +08:00

130 lines
2.7 KiB
Go

package middleware
import (
"strings"
"github.com/gin-gonic/gin"
"github.com/wmms/wmms/internal/service"
"github.com/wmms/wmms/pkg/response"
)
const (
AuthorizationHeader = "Authorization"
BearerPrefix = "Bearer "
UserIDKey = "user_id"
UsernameKey = "username"
RoleKey = "role"
)
// AuthMiddleware validates JWT tokens
func AuthMiddleware() gin.HandlerFunc {
authSvc := service.NewAuthService()
return func(c *gin.Context) {
authHeader := c.GetHeader(AuthorizationHeader)
if authHeader == "" {
response.Unauthorized(c, "missing authorization header")
c.Abort()
return
}
if !strings.HasPrefix(authHeader, BearerPrefix) {
response.Unauthorized(c, "invalid authorization format")
c.Abort()
return
}
tokenString := strings.TrimPrefix(authHeader, BearerPrefix)
token, err := authSvc.ValidateToken(tokenString)
if err != nil {
response.Unauthorized(c, "invalid or expired token")
c.Abort()
return
}
// Set user info in context
c.Set(UserIDKey, token.UserID)
c.Set(UsernameKey, token.Username)
c.Set(RoleKey, token.Role)
c.Next()
}
}
// AdminOnly middleware restricts access to admin role only
func AdminOnly() gin.HandlerFunc {
return func(c *gin.Context) {
role, exists := c.Get(RoleKey)
if !exists {
response.Unauthorized(c, "unauthorized")
c.Abort()
return
}
if role != "admin" {
response.Forbidden(c, "admin access required")
c.Abort()
return
}
c.Next()
}
}
// GetCurrentUserID returns the current user's ID from context
func GetCurrentUserID(c *gin.Context) int64 {
if id, exists := c.Get(UserIDKey); exists {
return id.(int64)
}
return 0
}
// GetCurrentUsername returns the current username from context
func GetCurrentUsername(c *gin.Context) string {
if username, exists := c.Get(UsernameKey); exists {
return username.(string)
}
return ""
}
// GetCurrentRole returns the current user's role from context
func GetCurrentRole(c *gin.Context) string {
if role, exists := c.Get(RoleKey); exists {
return role.(string)
}
return ""
}
// OptionalAuth middleware extracts user info if token is present but doesn't require it
func OptionalAuth() gin.HandlerFunc {
authSvc := service.NewAuthService()
return func(c *gin.Context) {
authHeader := c.GetHeader(AuthorizationHeader)
if authHeader == "" {
c.Next()
return
}
if !strings.HasPrefix(authHeader, BearerPrefix) {
c.Next()
return
}
tokenString := strings.TrimPrefix(authHeader, BearerPrefix)
token, err := authSvc.ValidateToken(tokenString)
if err != nil {
c.Next()
return
}
c.Set(UserIDKey, token.UserID)
c.Set(UsernameKey, token.Username)
c.Set(RoleKey, token.Role)
c.Next()
}
}