diff --git a/.gitignore b/.gitignore
index b0088e0..d17bf15 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
 .env
 tmp
 *.db
+imgs
\ No newline at end of file
diff --git a/internal/api/routes/upload.go b/internal/api/routes/upload.go
index baed591..d4950e7 100644
--- a/internal/api/routes/upload.go
+++ b/internal/api/routes/upload.go
@@ -4,22 +4,36 @@ import (
 	"path/filepath"
 
 	"github.com/gin-gonic/gin"
+	"github.com/golang-jwt/jwt/v5"
+	"stereo.cat/backend/internal/auth"
 	"stereo.cat/backend/internal/types"
 )
 
 func RegisterUploadRoutes(cfg *types.StereoConfig, api *gin.RouterGroup) {
-	api.POST("/upload", func(c *gin.Context) {
+	api.POST("/upload", auth.JwtMiddleware(cfg.JWTSecret), func(c *gin.Context) {
+		claims := c.MustGet("claims").(jwt.MapClaims)
+		user := claims["user"].(auth.User)
+
+		uid := user.ID
+
+		if uid == "" {
+			c.JSON(401, gin.H{"error": "unauthorized"})
+			return
+		}
+
 		file, err := c.FormFile("file")
 		if err != nil {
 			c.JSON(400, gin.H{"error": "file is required"})
 			return
 		}
 
-		filePath := filepath.Join(cfg.ImagePath, file.Filename)
+		filePath := filepath.Join(cfg.ImagePath, uid, file.Filename)
 		if err := c.SaveUploadedFile(file, filePath); err != nil {
 			c.JSON(500, gin.H{"error": "failed to save file"})
 			return
 		}
+
+		c.JSON(200, gin.H{"message": "file uploaded successfully"})
 	})
 
 	api.GET("/:name", func(c *gin.Context) {
diff --git a/internal/auth/jwt.go b/internal/auth/jwt.go
index 9e7aec2..1ea6d0f 100644
--- a/internal/auth/jwt.go
+++ b/internal/auth/jwt.go
@@ -11,9 +11,9 @@ import (
 )
 
 func GenerateJWT(key string, user User, expiryTimestamp uint64) (string, error) {
-	claims := jwt.MapClaims{
-		"user": user,
-		"exp":  expiryTimestamp,
+	claims := Claims{
+		User: user,
+		Exp:  expiryTimestamp,
 	}
 
 	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
diff --git a/internal/auth/types.go b/internal/auth/types.go
index a83b941..8627df7 100644
--- a/internal/auth/types.go
+++ b/internal/auth/types.go
@@ -1,6 +1,10 @@
 package auth
 
-import "time"
+import (
+	"time"
+
+	"github.com/golang-jwt/jwt/v5"
+)
 
 type TokenResponse struct {
 	AccessToken  string `json:"access_token"`
@@ -28,3 +32,9 @@ type ExchangeCodeRequest struct {
 	Code        string `json:"code"`
 	RedirectUri string `json:"redirect_uri"`
 }
+
+type Claims struct {
+	User User   `json:"user"`
+	Exp  uint64 `json:"exp"`
+	jwt.RegisteredClaims
+}