Auth middleware with JWT
This commit is contained in:
@@ -10,6 +10,8 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
JWT "github.com/golang-jwt/jwt"
|
||||
|
||||
res "backend/utils/responses"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -133,3 +135,13 @@ func Login(c *gin.Context) {
|
||||
// Return successful login
|
||||
res.Success(c, gin.H{"message": "Successfully logged in"})
|
||||
}
|
||||
|
||||
// Returns info from token middleware
|
||||
func TokenInfo(c *gin.Context) {
|
||||
user := c.MustGet("user").(JWT.MapClaims)
|
||||
res.Success(c, gin.H{
|
||||
"id": user["id"],
|
||||
"name": user["name"],
|
||||
"email": user["email"],
|
||||
})
|
||||
}
|
||||
|
||||
36
backend/middleware/middleware.go
Normal file
36
backend/middleware/middleware.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"backend/utils/jwt"
|
||||
res "backend/utils/responses"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func IsAuthenticated() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
// Get token from cookie
|
||||
token, err := c.Cookie("jwt-token")
|
||||
if err != nil {
|
||||
res.NeedsToLogin(c)
|
||||
return
|
||||
}
|
||||
|
||||
// Parse and check token
|
||||
parsed, err := jwt.ParseJWT(token)
|
||||
if err != nil {
|
||||
// Fail the request
|
||||
res.NeedsToLogin(c)
|
||||
return
|
||||
}
|
||||
|
||||
// Set user in context
|
||||
c.Set("user", parsed)
|
||||
|
||||
// Execute next middleware/request
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Implement middleware for accessing your specific template
|
||||
// Check if template exists, and is user template (type shi)
|
||||
@@ -2,6 +2,7 @@ package routes
|
||||
|
||||
import (
|
||||
"backend/controllers/user"
|
||||
"backend/middleware"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -13,5 +14,11 @@ func SetupRoutes() *gin.Engine {
|
||||
r.POST("/register", user.Register)
|
||||
r.POST("/login", user.Login)
|
||||
|
||||
// Authenticated routes middleware/group
|
||||
auth := r.Group("/")
|
||||
auth.Use(middleware.IsAuthenticated())
|
||||
|
||||
auth.GET("/info", user.TokenInfo) // Route to check if user is authenticated
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package jwt
|
||||
import (
|
||||
"backend/config"
|
||||
"backend/models/user"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt"
|
||||
@@ -28,3 +29,27 @@ func GenerateJWT(u *user.User) (string, error) {
|
||||
|
||||
return tokenString, nil
|
||||
}
|
||||
|
||||
func ParseJWT(tokenString string) (jwt.MapClaims, error) {
|
||||
mySigningKey := []byte(config.Env["JWT_SECRET"])
|
||||
|
||||
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (any, error) {
|
||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
||||
}
|
||||
|
||||
return mySigningKey, nil
|
||||
})
|
||||
// Check token parsing errors
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If good values then return
|
||||
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
|
||||
return claims, nil
|
||||
}
|
||||
|
||||
// Return on invalid token
|
||||
return nil, fmt.Errorf("invalid token")
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package responses
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
@@ -19,3 +21,11 @@ func Error(c *gin.Context, err string, code int) {
|
||||
"error": err,
|
||||
})
|
||||
}
|
||||
|
||||
func NeedsToLogin(c *gin.Context) {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{
|
||||
"success": false,
|
||||
"error": "Authentication required",
|
||||
"needsAuthentication": true, // only appears in this error
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user