summaryrefslogtreecommitdiff
path: root/internal/auth/auth.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/auth/auth.go')
-rw-r--r--internal/auth/auth.go68
1 files changed, 49 insertions, 19 deletions
diff --git a/internal/auth/auth.go b/internal/auth/auth.go
index 2826a47..b58af82 100644
--- a/internal/auth/auth.go
+++ b/internal/auth/auth.go
@@ -5,6 +5,7 @@ import (
"net/http"
"os"
"strings"
+ "time"
"github.com/golang-jwt/jwt/v5"
"github.com/joho/godotenv"
@@ -14,43 +15,72 @@ func init() {
godotenv.Load()
}
-var (
- jwtsecret = []byte(os.Getenv("JWT_SECRET"))
- algo = string(os.Getenv("JWT_ALGO"))
-)
+var jwtSecret = []byte(os.Getenv("JWT_SECRET"))
+
+const algo = "HS256"
+
+func GenerateJWT(userID string, duration time.Duration) (string, error) {
+ claims := jwt.MapClaims{
+ "sub": userID,
+ "exp": time.Now().Add(duration).Unix(),
+ "iat": time.Now().Unix(),
+ }
+
+ token := jwt.NewWithClaims(jwt.GetSigningMethod(algo), claims)
+ signedToken, err := token.SignedString(jwtSecret)
+ if err != nil {
+ return "", fmt.Errorf("failed to sign token: %w", err)
+ }
+
+ return signedToken, nil
+}
-func validateJWT(tokenString string, expectedAlg string) (bool, error) {
- token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
+func validateJWT(tokenString string, expectedAlg string) (jwt.MapClaims, error) {
+ token, err := jwt.Parse(tokenString, func(token *jwt.Token) (any, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("invalid token: %v", token.Header["alg"])
}
- if token.Header["alg"] != expectedAlg {
- return nil, fmt.Errorf("incorrect alg: %v", token.Header["alg"])
+ if token.Method != jwt.GetSigningMethod(expectedAlg) {
+ return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
- return jwtsecret, nil
+ return jwtSecret, nil
})
- if err != nil || !token.Valid {
- return false, err
+
+ if err != nil {
+ return nil, err
+ }
+
+ claims, ok := token.Claims.(jwt.MapClaims)
+ if !ok || !token.Valid {
+ return nil, fmt.Errorf("JWT validation failed: invalid claims")
}
- if _, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
- return true, nil
+ if exp, ok := claims["exp"].(float64); ok {
+ if int64(exp) < time.Now().Unix() {
+ return nil, fmt.Errorf("JWT validation failed: token expired")
+ }
}
- return false, fmt.Errorf("invalid token")
+
+ return claims, nil
}
-func Verifyrequest(r *http.Request) bool {
+func VerifyRequest(r *http.Request) (jwt.MapClaims, error) {
authHeader := r.Header.Get("Authorization")
if authHeader == "" {
- return false
+ return nil, fmt.Errorf("Missing Authorization header in request")
}
// expected: "Bearer <token>"
authSplit := strings.Split(authHeader, " ")
if len(authSplit) != 2 || authSplit[0] != "Bearer" {
- return false
+ return nil, fmt.Errorf("Malformed Authorization header in request")
}
token := authSplit[1]
- isValid, _ := validateJWT(token, algo)
- return isValid
+ claims, err := validateJWT(token, algo)
+ if err != nil {
+ fmt.Printf("JWT error: %v for token: %s\n", err, token)
+ return nil, err
+ }
+
+ return claims, nil
}