first commit
This commit is contained in:
91
app/middlewares/auth_middleware.go
Normal file
91
app/middlewares/auth_middleware.go
Normal file
@@ -0,0 +1,91 @@
|
||||
package middlewares
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
configs "goGin/config"
|
||||
"goGin/app/services"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"log"
|
||||
)
|
||||
|
||||
const authClaimsKey = "auth_claims"
|
||||
|
||||
func RequireAuth(c *gin.Context) {
|
||||
authHeader := strings.TrimSpace(c.GetHeader("Authorization"))
|
||||
if authHeader == "" {
|
||||
authLogf("auth: missing Authorization header path=%s", c.Request.URL.Path)
|
||||
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "authorization header is required"})
|
||||
return
|
||||
}
|
||||
|
||||
parts := strings.SplitN(authHeader, " ", 2)
|
||||
if len(parts) != 2 || !strings.EqualFold(parts[0], "Bearer") || strings.TrimSpace(parts[1]) == "" {
|
||||
authLogf("auth: invalid authorization format path=%s header=%s", c.Request.URL.Path, authHeader)
|
||||
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "invalid authorization format, expected: Bearer <token>"})
|
||||
return
|
||||
}
|
||||
|
||||
jwtService := services.NewJWTService()
|
||||
claims, err := jwtService.ValidateToken(strings.TrimSpace(parts[1]))
|
||||
if err != nil {
|
||||
authLogf("auth: invalid token path=%s error=%v", c.Request.URL.Path, err)
|
||||
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "invalid token"})
|
||||
return
|
||||
}
|
||||
if claims.TokenType != services.TokenTypeAccess {
|
||||
authLogf("auth: non-access token used path=%s token_type=%s", c.Request.URL.Path, claims.TokenType)
|
||||
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "access token required"})
|
||||
return
|
||||
}
|
||||
|
||||
c.Set(authClaimsKey, claims)
|
||||
c.Next()
|
||||
}
|
||||
|
||||
func RequireAdmin(c *gin.Context) {
|
||||
claims, ok := GetAuthClaims(c)
|
||||
if !ok {
|
||||
authLogf("auth: RequireAdmin missing claims path=%s", c.Request.URL.Path)
|
||||
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
|
||||
return
|
||||
}
|
||||
if !claims.IsAdmin {
|
||||
authLogf("auth: RequireAdmin forbidden path=%s user_id=%v", c.Request.URL.Path, claims.UserID)
|
||||
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "admin role required"})
|
||||
return
|
||||
}
|
||||
c.Next()
|
||||
}
|
||||
|
||||
func RequireNormalUser(c *gin.Context) {
|
||||
claims, ok := GetAuthClaims(c)
|
||||
if !ok {
|
||||
authLogf("auth: RequireNormalUser missing claims path=%s", c.Request.URL.Path)
|
||||
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
|
||||
return
|
||||
}
|
||||
if claims.IsAdmin {
|
||||
authLogf("auth: RequireNormalUser forbidden (admin tried to access) path=%s user_id=%v", c.Request.URL.Path, claims.UserID)
|
||||
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "only normal users can access this endpoint"})
|
||||
return
|
||||
}
|
||||
c.Next()
|
||||
}
|
||||
|
||||
func GetAuthClaims(c *gin.Context) (*services.JWTClaim, bool) {
|
||||
raw, exists := c.Get(authClaimsKey)
|
||||
if !exists {
|
||||
return nil, false
|
||||
}
|
||||
claims, ok := raw.(*services.JWTClaim)
|
||||
return claims, ok
|
||||
}
|
||||
|
||||
func authLogf(format string, args ...interface{}) {
|
||||
if configs.AppConfig != nil && configs.AppConfig.Debug {
|
||||
log.Printf(format, args...)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user