(FIX): Fixed the JWT handling, no need to fail.
We don't need to fail, but we do need a way to know when a user is logged in. The new domain(server) function IsLoggedIn will do just that!
This commit is contained in:
parent
4a0eed2fc6
commit
5e07383ab0
@ -1,10 +1,7 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/golang-jwt/jwt/v5"
|
"github.com/golang-jwt/jwt/v5"
|
||||||
@ -20,38 +17,20 @@ func DepedencyInjectionMiddleware(deps *domain.InjectedDependencies) gin.Handler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JwtAuthMiddleWare handles collection the JWT from the browser's cookies and setting the
|
||||||
|
// appropriate data. If the data is not found, this middleware will do effectively nothing, by not
|
||||||
|
// setting any values. Protected routes can use this lack of a value as a sign that the user is not
|
||||||
|
// logged in and direct the user to login.
|
||||||
func JwtAuthMiddleWare(jwtSecretKey []byte) gin.HandlerFunc {
|
func JwtAuthMiddleWare(jwtSecretKey []byte) gin.HandlerFunc {
|
||||||
return func(ctx *gin.Context) {
|
return func(ctx *gin.Context) {
|
||||||
// NOTE: Option One: From auth header
|
// JWT cookie not found
|
||||||
//
|
|
||||||
// authHeader := ctx.GetHeader("Authorization")
|
|
||||||
//
|
|
||||||
// if authHeader == "" {
|
|
||||||
// ctx.JSON(http.StatusUnauthorized, gin.H{"error": "Authorization required."})
|
|
||||||
// ctx.Abort()
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// parts := strings.SplitN(authHeader, " ", 2)
|
|
||||||
// if !(len(parts) == 2 && parts[0] == "Bearer") {
|
|
||||||
// ctx.JSON(http.StatusUnauthorized, gin.H{"error": "Authorization header must be Bearer token"})
|
|
||||||
// ctx.Abort()
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// tokenString := parts[1]
|
|
||||||
|
|
||||||
// TODO: How are we handling faliure?
|
|
||||||
|
|
||||||
tokenString, err := ctx.Cookie("jwt_token")
|
tokenString, err := ctx.Cookie("jwt_token")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.JSON(http.StatusUnauthorized, gin.H{"error": "JWT token cookie not found"})
|
ctx.Next()
|
||||||
ctx.Abort()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
claims := &domain.JwtClaims{}
|
claims := &domain.JwtClaims{}
|
||||||
// token, err := jwt.ParseWithClaims(tokenString, claims, )
|
|
||||||
|
|
||||||
token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
|
token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
|
||||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||||
@ -60,22 +39,29 @@ func JwtAuthMiddleWare(jwtSecretKey []byte) gin.HandlerFunc {
|
|||||||
return jwtSecretKey, nil
|
return jwtSecretKey, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Error occurred when parsing
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, jwt.ErrSignatureInvalid) {
|
ctx.Next()
|
||||||
ctx.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token signature"})
|
|
||||||
} else if errors.Is(err, jwt.ErrTokenExpired) || errors.Is(err, jwt.ErrTokenNotValidYet) {
|
|
||||||
ctx.JSON(http.StatusUnauthorized, gin.H{"error": "Token expired or not yet valid"})
|
|
||||||
} else {
|
|
||||||
log.Printf("JWT parsing error: %v", err)
|
|
||||||
ctx.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"})
|
|
||||||
}
|
|
||||||
ctx.Abort()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: If we need deeper error handling
|
||||||
|
// if err != nil {
|
||||||
|
// if errors.Is(err, jwt.ErrSignatureInvalid) {
|
||||||
|
// ctx.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token signature"})
|
||||||
|
// } else if errors.Is(err, jwt.ErrTokenExpired) || errors.Is(err, jwt.ErrTokenNotValidYet) {
|
||||||
|
// ctx.JSON(http.StatusUnauthorized, gin.H{"error": "Token expired or not yet valid"})
|
||||||
|
// } else {
|
||||||
|
// log.Printf("JWT parsing error: %v", err)
|
||||||
|
// ctx.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"})
|
||||||
|
// }
|
||||||
|
// ctx.Abort()
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Token is invalid
|
||||||
if !token.Valid {
|
if !token.Valid {
|
||||||
ctx.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"})
|
ctx.Next()
|
||||||
ctx.Abort()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -135,6 +135,11 @@ func (s *Server) Setup() *Server {
|
|||||||
// API router endpoints
|
// API router endpoints
|
||||||
router_api.GET("/", func(ctx *gin.Context) { ctx.JSON(200, gin.H{"message": "Server is active."}) })
|
router_api.GET("/", func(ctx *gin.Context) { ctx.JSON(200, gin.H{"message": "Server is active."}) })
|
||||||
router_api.GET("/tmp", func(ctx *gin.Context) {
|
router_api.GET("/tmp", func(ctx *gin.Context) {
|
||||||
|
if !domain.IsLoggedIn(ctx) {
|
||||||
|
ctx.JSON(200, gin.H{"error": "User is not logged in. Please login to continue"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
userId := ctx.MustGet("userId").(int)
|
userId := ctx.MustGet("userId").(int)
|
||||||
userEmail := ctx.MustGet("userEmail").(string)
|
userEmail := ctx.MustGet("userEmail").(string)
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package domain
|
package domain
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/golang-jwt/jwt/v5"
|
"github.com/golang-jwt/jwt/v5"
|
||||||
domainAuth "github.com/haydenhargreaves/Potion/internal/domain/auth"
|
domainAuth "github.com/haydenhargreaves/Potion/internal/domain/auth"
|
||||||
domainUser "github.com/haydenhargreaves/Potion/internal/domain/user"
|
domainUser "github.com/haydenhargreaves/Potion/internal/domain/user"
|
||||||
@ -16,3 +17,10 @@ type JwtClaims struct {
|
|||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
jwt.RegisteredClaims
|
jwt.RegisteredClaims
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsLoggedIn checks the cookies in a request and returns whether the user is logged in.
|
||||||
|
func IsLoggedIn(ctx *gin.Context) bool {
|
||||||
|
_, id := ctx.Get("userId")
|
||||||
|
_, email := ctx.Get("userEmail")
|
||||||
|
return id && email
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user