Go fiber with session
Tags: go, fiber, session
Published: 2021-02-17 14:35:45

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

---
main.go
```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"))
}

```
---
views/index.html
```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>
```
---
ดูจาก log ที่เกิดจากการ request เข้ามา 
```shell

ทุกครั้งที่ยังไม่ได้ 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}
```
---
แต่ถ้า api เรามีการ compile ใหม่ ทำให้ค่า store เปลี่ยนใหม่ session ทั้งหมดจะถูกทำลายทันที

จริงๆ แล้ว package fiber session มันอำนวยความสำดวกให้เราเฉยๆ โดยการที่
- สร้าง uuid ขึ้นมาให้เมื่อไม่พบว่า request นั้นมีการแนบ cookie มาให้
- ใน method save มันก็จะ แนบ uuid เข้าไปใน fiber context cookie ให้ก่อนการส่ง response ออกไป

## ปัญหาที่เจอ
- Cookie แนบมากับหลังบ้าน แต่หน้าบ้านไม่เก็บ cookie เมื่อใช้งาน axios
> เราต้องไปตั้งค่า axios 2 อย่าง
```javascript
axios.defaults.baseURL = `${BASE_URL}`
axios.defaults.withCredentials = true
```