package main import ( "fmt" "log" "math/rand/v2" "sync" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/logger" ) func main() { app := fiber.New() app.Use(logger.New()) app.Post("/api/v3/auth/login", handleLogin) app.Get("/api/v3/auth/check", handleAuthCheck) app.Get("/api/v3/auth/401", func(c *fiber.Ctx) error { return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{ "err": "custom err 401", }) }) log.Fatal(app.Listen(":3000")) } type User struct { Username string `json:"username"` Password string `json:"password"` } var ( store = &sync.Map{} letters = []byte("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") mockUsers = map[string]User{ "admin": { Username: "admin", Password: "123456", }, "user": { Username: "user", Password: "12345678", }, } ) func randomString(n int) string { b := make([]byte, n) for i := range b { b[i] = letters[rand.IntN(len(letters))] } return string(b) } func handleLogin(c *fiber.Ctx) error { type Req struct { Username string `json:"username"` Password string `json:"password"` } var ( err error req Req ) if err = c.BodyParser(&req); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "error": err.Error(), }) } user, ok := mockUsers[req.Username] if !ok { return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{ "error": "user not found", }) } session := randomString(16) store.Store(session, user) c.Response().Header.Set("Set-Cookie", fmt.Sprintf("session=%s; Path=/; HttpOnly; SameSite=Lax", session)) c.Response().Header.Set("Server", "Fiber") return c.Status(fiber.StatusOK).JSON(user) } func handleAuthCheck(c *fiber.Ctx) error { session := c.Cookies("session") if session == "" { return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{ "error": "unauthorized", }) } user, ok := store.Load(session) if !ok { return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{ "error": "unauthorized", }) } return c.Status(fiber.StatusOK).JSON(user) }