Auth middleware with JWT

This commit is contained in:
Leons Aleksandrovs
2025-07-06 18:13:26 +03:00
parent 3003a961b6
commit d18f9f9706
5 changed files with 90 additions and 0 deletions

View File

@@ -10,6 +10,8 @@ import (
"log"
"net/http"
JWT "github.com/golang-jwt/jwt"
res "backend/utils/responses"
"github.com/gin-gonic/gin"
@@ -133,3 +135,13 @@ func Login(c *gin.Context) {
// Return successful login
res.Success(c, gin.H{"message": "Successfully logged in"})
}
// Returns info from token middleware
func TokenInfo(c *gin.Context) {
user := c.MustGet("user").(JWT.MapClaims)
res.Success(c, gin.H{
"id": user["id"],
"name": user["name"],
"email": user["email"],
})
}

View File

@@ -0,0 +1,36 @@
package middleware
import (
"backend/utils/jwt"
res "backend/utils/responses"
"github.com/gin-gonic/gin"
)
func IsAuthenticated() gin.HandlerFunc {
return func(c *gin.Context) {
// Get token from cookie
token, err := c.Cookie("jwt-token")
if err != nil {
res.NeedsToLogin(c)
return
}
// Parse and check token
parsed, err := jwt.ParseJWT(token)
if err != nil {
// Fail the request
res.NeedsToLogin(c)
return
}
// Set user in context
c.Set("user", parsed)
// Execute next middleware/request
c.Next()
}
}
// TODO: Implement middleware for accessing your specific template
// Check if template exists, and is user template (type shi)

View File

@@ -2,6 +2,7 @@ package routes
import (
"backend/controllers/user"
"backend/middleware"
"github.com/gin-gonic/gin"
)
@@ -13,5 +14,11 @@ func SetupRoutes() *gin.Engine {
r.POST("/register", user.Register)
r.POST("/login", user.Login)
// Authenticated routes middleware/group
auth := r.Group("/")
auth.Use(middleware.IsAuthenticated())
auth.GET("/info", user.TokenInfo) // Route to check if user is authenticated
return r
}

View File

@@ -3,6 +3,7 @@ package jwt
import (
"backend/config"
"backend/models/user"
"fmt"
"time"
"github.com/golang-jwt/jwt"
@@ -28,3 +29,27 @@ func GenerateJWT(u *user.User) (string, error) {
return tokenString, nil
}
func ParseJWT(tokenString string) (jwt.MapClaims, error) {
mySigningKey := []byte(config.Env["JWT_SECRET"])
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (any, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return mySigningKey, nil
})
// Check token parsing errors
if err != nil {
return nil, err
}
// If good values then return
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
return claims, nil
}
// Return on invalid token
return nil, fmt.Errorf("invalid token")
}

View File

@@ -1,6 +1,8 @@
package responses
import (
"net/http"
"github.com/gin-gonic/gin"
)
@@ -19,3 +21,11 @@ func Error(c *gin.Context, err string, code int) {
"error": err,
})
}
func NeedsToLogin(c *gin.Context) {
c.JSON(http.StatusUnauthorized, gin.H{
"success": false,
"error": "Authentication required",
"needsAuthentication": true, // only appears in this error
})
}