Files
GoMembership/internal/middlewares/auth.go
$(pass /github/name) ff7c83671f fix: auth && auth_test
2024-09-07 08:53:57 +02:00

110 lines
2.4 KiB
Go

package middlewares
import (
"GoMembership/internal/config"
"GoMembership/pkg/logger"
"fmt"
"net/http"
"time"
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt/v5"
)
var (
jwtKey = []byte(config.Auth.JWTSecret)
jwtSigningMethod = jwt.SigningMethodHS256
jwtParser = jwt.NewParser(jwt.WithValidMethods([]string{jwtSigningMethod.Alg()}))
)
func GenerateToken(userID int64) (string, error) {
token := jwt.NewWithClaims(jwtSigningMethod, jwt.MapClaims{
"user_id": userID,
"exp": time.Now().Add(time.Minute * 10).Unix(), // Token expires in 10 Minutes
})
logger.Error.Printf("token generated: %#v", token)
return token.SignedString(jwtKey)
}
func verifyToken(tokenString string) (*jwt.Token, error) {
if tokenString == "" {
return nil, fmt.Errorf("Authorization token is required")
}
token, err := jwtParser.Parse(tokenString, func(_ *jwt.Token) (interface{}, error) {
return jwtKey, nil
})
if err != nil {
return nil, err
}
if !token.Valid {
return nil, fmt.Errorf("invalid token")
}
claims, ok := token.Claims.(jwt.MapClaims)
if !ok {
return nil, fmt.Errorf("invalid token claims")
}
exp, ok := claims["exp"].(float64)
if !ok {
return nil, fmt.Errorf("invalid expiration claim")
}
userID, ok := claims["user_id"].(float64)
if !ok {
logger.Error.Printf("Invalid user ID: %v", userID)
return nil, fmt.Errorf("Invalid user ID")
}
if time.Now().Unix() > int64(exp) {
return nil, fmt.Errorf("token expired")
}
return token, nil
}
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
tokenString, err := c.Cookie("jwt")
if err != nil {
logger.Error.Printf("No Auth token: %v\n", err)
c.JSON(http.StatusUnauthorized, gin.H{"error": "No Auth token"})
c.Abort()
return
}
token, err := verifyToken(tokenString)
if err != nil {
logger.Error.Printf("Token is invalid: %v\n", err)
c.JSON(http.StatusUnauthorized, gin.H{"error": "Auth token invalid"})
c.Abort()
return
}
claims, _ := token.Claims.(jwt.MapClaims)
userID, _ := claims["user_id"].(float64)
// Generate a new token
newToken, err := GenerateToken(int64(userID))
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to refresh token"})
c.Abort()
return
}
c.SetCookie(
"jwt",
newToken,
10*60, // 10 minutes
"/",
"",
true,
true,
)
c.Set("user_id", userID)
c.Next()
}
}