feat(auth): Add logout route

This commit is contained in:
Björn Benouarets
2026-01-19 09:23:25 +01:00
parent 88dadab6a2
commit 9d7adb740c
4 changed files with 122 additions and 0 deletions

42
app/controllers/logout.go Normal file
View File

@@ -0,0 +1,42 @@
package controllers
import (
"git.secnex.io/secnex/auth-api/services"
"git.secnex.io/secnex/auth-api/utils"
"git.secnex.io/secnex/masterlog"
"github.com/go-playground/validator/v10"
"github.com/gofiber/fiber/v2"
)
type LogoutRequest struct {
SessionToken string `json:"token" validate:"required"`
}
func LogoutController(c *fiber.Ctx) error {
var request LogoutRequest
if err := c.BodyParser(&request); err != nil {
return utils.NewErrorResponse(fiber.StatusBadRequest, &fiber.Map{
"message": "Invalid request body",
}).Send(c)
}
masterlog.Debug("Processing logout request", map[string]interface{}{"session_token": request.SessionToken})
validate := validator.New()
if err := validate.Struct(request); err != nil {
return utils.NewErrorResponse(fiber.StatusBadRequest, &fiber.Map{
"message": "Invalid request body",
}).Send(c)
}
err := services.Logout(request.SessionToken)
if err != nil {
return utils.NewErrorResponse(fiber.StatusInternalServerError, &fiber.Map{
"message": "Error logging out",
}).Send(c)
}
return utils.NewHTTPResponse(fiber.StatusOK, &fiber.Map{
"message": "OK",
}, "", nil, nil).Send(c)
}

View File

@@ -65,6 +65,7 @@ func main() {
// Controllers
app.Post("/login", controllers.LoginController)
app.Post("/register", controllers.RegisterController)
app.Post("/logout", controllers.LogoutController)
app.Post("/session/info", controllers.SessionInfoController)
if config.ENV == "development" {

View File

@@ -97,3 +97,31 @@ func GetSessionCache(sessionID string) *SessionDetails {
masterlog.Debug("Session retrieved from cache", map[string]interface{}{"session_id": sessionID, "user_id": sessionDetails.UserID})
return &sessionDetails
}
func DeleteSession(sessionID string) error {
masterlog.Debug("Deleting session from database and cache", map[string]interface{}{"session_id": sessionID})
if err := DeleteSessionCache(sessionID); err != nil {
masterlog.Debug("Failed to delete session from cache", map[string]interface{}{"error": err.Error(), "session_id": sessionID})
return err
}
if err := database.DB.Where("id = ?", sessionID).Delete(&models.Session{}).Error; err != nil {
masterlog.Debug("Failed to delete session from database", map[string]interface{}{"error": err.Error(), "session_id": sessionID})
return err
}
masterlog.Debug("Session deleted from database and cache", map[string]interface{}{"session_id": sessionID})
return nil
}
func DeleteSessionCache(sessionID string) error {
masterlog.Debug("Deleting session from cache", map[string]interface{}{"session_id": sessionID})
if cache.Cache.Client == nil {
masterlog.Debug("Redis client not initialized", map[string]interface{}{"session_id": sessionID})
return nil
}
if err := cache.Cache.Client.Do(cache.Cache.Context, cache.Cache.Client.B().Del().Key(sessionID).Build()).Error(); err != nil {
masterlog.Debug("Failed to delete session from cache", map[string]interface{}{"error": err.Error(), "session_id": sessionID})
return err
}
masterlog.Debug("Session deleted from cache", map[string]interface{}{"session_id": sessionID})
return nil
}

51
app/services/logout.go Normal file
View File

@@ -0,0 +1,51 @@
package services
import (
"errors"
"fmt"
"git.secnex.io/secnex/auth-api/config"
"git.secnex.io/secnex/auth-api/repositories"
"github.com/golang-jwt/jwt/v5"
"github.com/google/uuid"
)
func Logout(sessionToken string) error {
claims, err := jwt.ParseWithClaims(sessionToken, &jwt.MapClaims{}, func(token *jwt.Token) (interface{}, error) {
return []byte(config.CONFIG.JwtSecret), nil
})
if err != nil {
return err
}
if !claims.Valid {
return errors.New("invalid token")
}
mapClaims := claims.Claims.(*jwt.MapClaims)
subValue, ok := (*mapClaims)["sub"]
if !ok {
return errors.New("sub claim not found")
}
var sessionID string
switch v := subValue.(type) {
case string:
sessionID = v
case uuid.UUID:
sessionID = v.String()
default:
sessionID = fmt.Sprintf("%v", v)
}
err = repositories.DeleteSessionCache(sessionID)
if err != nil {
return err
}
err = repositories.DeleteSession(sessionID)
if err != nil {
return err
}
return nil
}