DEV Community

Perm Chao
Perm Chao

Posted on • Edited on

2

Go fiber with session

ทดลองการใช้งาน Go Fiber กับ middleware ตัวหนึ่งชื่อว่า session


main.go

func main() {
    store := session.New()

    engine := html.New("./views", ".html")
    engine.Reload(true)
    engine.Debug(true)
    engine.Layout("embed")
    engine.Delims("{{", "}}")
    app := fiber.New(fiber.Config{
        Views: engine,
    })

    app.Get("/", func(c *fiber.Ctx) error {
        sess, err := store.Get(c)
        if err != nil {
            log.Println(err)
        }

        log.Println(sess)
        name := sess.Get("name")
        isLogin := name != nil
        UnauthorizedMessage := "You are not login"
        AuthorizedMessage := fmt.Sprintf("Welcome %v", name)

        return c.Render("index", fiber.Map{
            "AuthorizedMessage":   AuthorizedMessage,
            "UnauthorizedMessage": UnauthorizedMessage,
            "IsLogin":             isLogin,
        })
    })

    app.Get("/login", func(c *fiber.Ctx) error {
        sess, err := store.Get(c)
        if err != nil {
            panic(err)
        }

        sess.Set("name", c.Query("name", "unknown user"))
        if err := sess.Save(); err != nil {
            panic(err)
        }

        return c.Redirect("/")
    })

    app.Get("/logout", func(c *fiber.Ctx) error {
        sess, err := store.Get(c)
        if err != nil {
            panic(err)
        }

        sess.Delete("name")

        // Destry session
        if err := sess.Destroy(); err != nil {
            panic(err)
        }

        return c.Redirect("/")
    })

    log.Fatal(app.Listen(":3000"))
}

Enter fullscreen mode Exit fullscreen mode

views/index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  {{if .IsLogin}}
    {{.AuthorizedMessage}}
  {{else}}
    {{.UnauthorizedMessage}}
    <form action="/login">
      <label for="fname">Your name</label><br>
      <input type="text" id="name" name="name"><br>
      <input type="submit" value="Login">
    </form> 
  {{end}}
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

ดูจาก log ที่เกิดจากการ request เข้ามา


ทุกครั้งที่ยังไม่ได้ save session รหัสจะเปลี่ยนไปเรื่อย
21:9:12 app         | 2021/02/17 21:09:12 &{5924577f-195a-4342-90c5-33d08322d3ac true 0xc00013cb00 0xc000202150 0xc000262960}
21:9:19 app         | 2021/02/17 21:09:19 &{20b172d6-7836-46e7-9b84-cbd22cea7e28 true 0xc00013cb00 0xc000202150 0xc000262b60}
21:16:58 app         | 2021/02/17 21:16:58 &{4f1bf90a-ca51-4b20-a69f-3263cf41aa17 false 0xc00009e000 0xc000202150 0xc0000e1120}

แต่หลังจากมีการ login ได้มีการ save session แล้ว ตัว session นั้น รหัสจะไม่เปลี่ยน
21:2:36 app         | 2021/02/17 21:02:36 &{4f1bf90a-ca51-4b20-a69f-3263cf41aa17 false 0xc00029e000 0xc000202150 0xc0002900a0}
21:2:36 app         | views: parsed template: index
21:2:50 app         | 2021/02/17 21:02:50 &{4f1bf90a-ca51-4b20-a69f-3263cf41aa17 false 0xc00029e000 0xc000202150 0xc0002903e0}
21:2:50 app         | views: parsed template: index
21:2:55 app         | 2021/02/17 21:02:55 &{4f1bf90a-ca51-4b20-a69f-3263cf41aa17 false 0xc00029e000 0xc000202150 0xc000290620}
Enter fullscreen mode Exit fullscreen mode

แต่ถ้า api เรามีการ compile ใหม่ ทำให้ค่า store เปลี่ยนใหม่ session ทั้งหมดจะถูกทำลายทันที

จริงๆ แล้ว package fiber session มันอำนวยความสำดวกให้เราเฉยๆ โดยการที่

  • สร้าง uuid ขึ้นมาให้เมื่อไม่พบว่า request นั้นมีการแนบ cookie มาให้
  • ใน method save มันก็จะ แนบ uuid เข้าไปใน fiber context cookie ให้ก่อนการส่ง response ออกไป

ปัญหาที่เจอ

  • Cookie แนบมากับหลังบ้าน แต่หน้าบ้านไม่เก็บ cookie เมื่อใช้งาน axios > เราต้องไปตั้งค่า axios 2 อย่าง
axios.defaults.baseURL = `${BASE_URL}`
axios.defaults.withCredentials = true
Enter fullscreen mode Exit fullscreen mode

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (2)

Collapse
 
vietlib profile image
vietlib

how can i declare session middleware in app.go and using session middleware in other package (for example: user package) ? thank you

Collapse
 
mossnana profile image
Perm Chao

In my opinion, use store method func (s *Store) Get(c *fiber.Ctx) (*Session, error)
by pass store into your other package.

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay