Skip to content

Commit dc79d5e

Browse files
committed
feat : jwt and middlewear
1 parent 21650d7 commit dc79d5e

File tree

4 files changed

+115
-10
lines changed

4 files changed

+115
-10
lines changed

src/controllers/authControllers.go

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,16 @@ import (
55
"gin-mongo-api/src/database"
66
"gin-mongo-api/src/models"
77
"gin-mongo-api/src/res"
8+
"gin-mongo-api/src/utils"
9+
"net/http"
10+
"time"
11+
812
"github.com/gin-gonic/gin"
913
"github.com/go-playground/validator/v10"
1014
"go.mongodb.org/mongo-driver/bson"
1115
"go.mongodb.org/mongo-driver/bson/primitive"
1216
"go.mongodb.org/mongo-driver/mongo"
1317
"golang.org/x/crypto/bcrypt"
14-
"net/http"
15-
"time"
1618
)
1719

1820
var userCollection *mongo.Collection = database.GetCollection(database.DB, "users")
@@ -78,6 +80,7 @@ func Greeting() gin.HandlerFunc {
7880
}
7981
}
8082

83+
8184
func Login() gin.HandlerFunc {
8285
return func(c *gin.Context) {
8386
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
@@ -97,22 +100,42 @@ func Login() gin.HandlerFunc {
97100
existingUser := models.User{}
98101
err := userCollection.FindOne(ctx, bson.M{"email": loginData.Email}).Decode(&existingUser)
99102
if err == mongo.ErrNoDocuments {
100-
101103
c.JSON(http.StatusNotFound, res.UserResponse{Status: http.StatusNotFound, Message: "error", Data: map[string]interface{}{"data": "User not found"}})
102104
return
103105
} else if err != nil {
104-
105106
c.JSON(http.StatusInternalServerError, res.UserResponse{Status: http.StatusInternalServerError, Message: "error", Data: map[string]interface{}{"data": err.Error()}})
106107
return
107108
}
108109

109110
err = bcrypt.CompareHashAndPassword([]byte(existingUser.Password), []byte(loginData.Password))
110111
if err != nil {
111-
112112
c.JSON(http.StatusUnauthorized, res.UserResponse{Status: http.StatusUnauthorized, Message: "error", Data: map[string]interface{}{"data": "Invalid credentials"}})
113113
return
114114
}
115115

116-
c.JSON(http.StatusOK, res.UserResponse{Status: http.StatusOK, Message: "success", Data: map[string]interface{}{"data": "Login successful"}})
116+
117+
118+
token, err := utils.GenerateJWTToken(existingUser.ID.Hex())
119+
if err != nil {
120+
c.JSON(http.StatusInternalServerError, res.UserResponse{Status: http.StatusInternalServerError, Message: "error", Data: map[string]interface{}{"data": "Failed to generate JWT token"}})
121+
return
122+
}
123+
124+
125+
c.Header("Authorization", "Bearer "+token)
126+
127+
128+
cookie := http.Cookie{
129+
Name: "jwt",
130+
Value: token,
131+
Expires: time.Now().Add(24 * time.Hour),
132+
HttpOnly: true,
133+
Secure: true,
134+
SameSite: http.SameSiteStrictMode,
135+
}
136+
http.SetCookie(c.Writer, &cookie)
137+
138+
139+
c.JSON(http.StatusOK, res.UserResponse{Status: http.StatusOK, Message: "success", Data: map[string]interface{}{"data": "Login successful", "token": token}})
117140
}
118141
}

src/middlewear/authMiddlewear.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package middleware
2+
3+
import (
4+
"gin-mongo-api/src/utils"
5+
"net/http"
6+
"strings"
7+
8+
"github.com/gin-gonic/gin"
9+
)
10+
11+
func AuthMiddleware() gin.HandlerFunc {
12+
return func(c *gin.Context) {
13+
authorizationHeader := c.Request.Header.Get("Authorization")
14+
if authorizationHeader == "" {
15+
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
16+
"error": "Unauthorized",
17+
})
18+
return
19+
}
20+
tokenParts := strings.Split(authorizationHeader, " ")
21+
if len(tokenParts) != 2 || tokenParts[0] != "Bearer" {
22+
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
23+
"error": "Invalid Authorization header format",
24+
})
25+
return
26+
}
27+
token := tokenParts[1]
28+
29+
claims, err := utils.ValidateJWTToken(token)
30+
if err != nil {
31+
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
32+
"error": "Invalid token",
33+
})
34+
return
35+
}
36+
37+
c.Set("userId", claims["userId"])
38+
c.Next()
39+
}
40+
}

src/routes/userRoutes.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package routes
22

33
import ("github.com/gin-gonic/gin"
4-
"gin-mongo-api/src/controllers")
4+
"gin-mongo-api/src/controllers"
5+
"gin-mongo-api/src/middlewear"
6+
)
57

68
func UserRoute(router *gin.Engine) {
7-
router.GET("/",controllers.Greeting())
8-
router.POST("/register", controllers.Register());
9-
router.POST("/login",controllers.Login())
9+
10+
router.GET("/",middleware.AuthMiddleware(),controllers.Greeting())
11+
apiGroup := router.Group("/api/auth")
12+
apiGroup.POST("/register", controllers.Register());
13+
apiGroup.POST("/login",controllers.Login())
1014
};

src/utils/jwt.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package utils
2+
3+
import (
4+
"fmt"
5+
"time"
6+
7+
"github.com/dgrijalva/jwt-go"
8+
)
9+
10+
var jwtSecret = []byte("your-secret-key")
11+
12+
func ValidateJWTToken(tokenString string) (jwt.MapClaims, error) {
13+
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
14+
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
15+
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
16+
}
17+
return jwtSecret, nil
18+
})
19+
20+
if err != nil {
21+
return nil, err
22+
}
23+
24+
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
25+
return claims, nil
26+
}
27+
28+
return nil, fmt.Errorf("Invalid token")
29+
}
30+
31+
func GenerateJWTToken(userID string) (string, error) {
32+
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
33+
"userId": userID,
34+
"exp": time.Now().Add(time.Hour * 24).Unix(),
35+
})
36+
37+
return token.SignedString(jwtSecret)
38+
}

0 commit comments

Comments
 (0)