From 6e189d2ff0d4f70b2a1723a0f2d0276e76fa0b23 Mon Sep 17 00:00:00 2001 From: Arthur Lefebvre Date: Fri, 3 Oct 2025 19:51:50 +0200 Subject: [PATCH] Check authentication from jwt on all routes --- internal/jwtauth/jwt.go | 5 +--- internal/jwtauth/key.go | 4 +++ internal/middleware/auth.go | 52 +++++++++++++++++++++++++++++++++++++ main.go | 2 ++ 4 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 internal/middleware/auth.go diff --git a/internal/jwtauth/jwt.go b/internal/jwtauth/jwt.go index 70ab423..b3cd626 100644 --- a/internal/jwtauth/jwt.go +++ b/internal/jwtauth/jwt.go @@ -1,15 +1,12 @@ package jwtauth import ( - "encoding/base64" - "os" - "github.com/golang-jwt/jwt/v5" ) func GenerateJwtToken(username string) (string, error) { var s string - key, err := base64.URLEncoding.DecodeString(os.Getenv(getKeyVariableName())) + key, err := GetJwtKey() if err != nil { return s, err } diff --git a/internal/jwtauth/key.go b/internal/jwtauth/key.go index 2c277e1..34aa2ee 100644 --- a/internal/jwtauth/key.go +++ b/internal/jwtauth/key.go @@ -37,3 +37,7 @@ func InitKey() error { } return err } + +func GetJwtKey() ([]byte, error) { + return base64.URLEncoding.DecodeString(os.Getenv(getKeyVariableName())) +} diff --git a/internal/middleware/auth.go b/internal/middleware/auth.go new file mode 100644 index 0000000..fe950b1 --- /dev/null +++ b/internal/middleware/auth.go @@ -0,0 +1,52 @@ +package middleware + +import ( + "fmt" + "net/http" + "strings" + + "git.artlef.fr/PersonalLibraryManager/internal/jwtauth" + "github.com/gin-gonic/gin" + "github.com/golang-jwt/jwt/v5" +) + +func Auth() gin.HandlerFunc { + return func(c *gin.Context) { + + //do not check current user if we are creating an account or logging in + if strings.HasPrefix(c.FullPath(), "/auth") { + return + } + + username, err := parseUserFromJwt(c) + if err != nil { + fmt.Println(err) + c.AbortWithStatusJSON(http.StatusUnauthorized, + gin.H{"error": "You must be logged in to access this resource."}) + } else { + c.Set("user", username) + } + } +} + +func parseUserFromJwt(c *gin.Context) (string, error) { + + jwtokenStr := jwtFromBearerToken(c.GetHeader("Authorization")) + jwtoken, parseErr := jwt.Parse(jwtokenStr, + func(token *jwt.Token) (any, error) { + return jwtauth.GetJwtKey() + }, jwt.WithValidMethods([]string{jwt.SigningMethodHS256.Alg()})) + if parseErr != nil { + return "", parseErr + } + return jwtoken.Claims.GetSubject() +} + +func jwtFromBearerToken(bearerToken string) string { + splitToken := strings.Split(bearerToken, " ") + if len(splitToken) == 2 { + return splitToken[1] + } else { + return "" + } +} diff --git a/main.go b/main.go index 82048bc..e679285 100644 --- a/main.go +++ b/main.go @@ -8,6 +8,7 @@ import ( "git.artlef.fr/PersonalLibraryManager/internal/config" "git.artlef.fr/PersonalLibraryManager/internal/db" "git.artlef.fr/PersonalLibraryManager/internal/jwtauth" + "git.artlef.fr/PersonalLibraryManager/internal/middleware" ) func main() { @@ -24,6 +25,7 @@ func setup(config *config.Config) *gin.Engine { } r := gin.Default() r.Use(cors.Default()) // All origins allowed by default + r.Use(middleware.Auth()) r.GET("/books", func(c *gin.Context) { api.GetBooksHanderl(c, db) })