똑같은 삽질은 2번 하지 말자

Golang vol.3 본문

Go

Golang vol.3

곽빵 2022. 4. 25. 23:00

개요

고랭 학습하면서 느낀점이나 기록하면 좋을법한 내용들을 정리

 

1. 더미데이터 만들때 좋은 패키지

go get -u github.com/bxcodec/faker/v3

usage

package main

import (
	"ambassador/src/database"
	"ambassador/src/models"

	"github.com/bxcodec/faker/v3"
)

func main() {
	database.Connect()

	for i := 0; i < 30; i++ {
		ambassador := models.User{
			FirstName:    faker.FirstName(),
			LastName:     faker.LastName(),
			Email:        faker.Email(),
			IsAmbassador: true,
		}

		ambassador.SetPassword("1234")

		database.DB.Create(&ambassador)
	}
}

 

2. go의 console log

import (
	"log"
)

func Example(c *fiber.Ctx) error {
	log.Printf("%v", c)

}

 

3. model의 공통 column(or field)를 추상화 하는 이하의 방법이 있다.

package models

type Model struct {
	Id uint `json:"id"`
}

// product.go
package models

type Product struct {
	Model
	Title       string  `json:"title"`
	Description string  `json:"description"`
	Image       string  `json:"image"`
	Price       float64 `json:"price"`
}

// user.go
package models

type Product struct {
	Model
	Title       string  `json:"title"`
	Description string  `json:"description"`
	Image       string  `json:"image"`
	Price       float64 `json:"price"`
}

 

4. SQL 로그 남기기

LogLevel을 logger.info로 함으로써 모든 sql로그들이 출력되게 된다.

newLogger := logger.New(
    log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
    logger.Config{
        SlowThreshold:             time.Second, // Slow SQL threshold
        LogLevel:                  logger.Info, // Log level slient 1 ~ info 4
        IgnoreRecordNotFoundError: true,        // Ignore ErrRecordNotFound error for logger
        Colorful:                  true,        // Disable color
    },
)

// populate log pre-fields here before set to
DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
    Logger: newLogger,
})

 

5. model의 field 메소드 정의할 때 주의할 점

 

6. JWT에 유저별로 scope 설정하기

ClaimsWithScope라는 구조체를 하나 만들어서 Scope를 가진 Claims(속성정보)를 만들어 준다.

 

jwt.ParseWithClaims로 쿠키와 구조체 비밀키를 넣으면 로그인할 때 설정한 claim을 얻을 수 있는데, 

그 안에 scope도 잘 설정되어 있다.

const SecretKey = "secret"

type ClaimsWithScope struct {
	jwt.StandardClaims // 이 안에 있는 요소들이 distructuring 하는것 처럼 풀어서 들어가는것 같다.
	Scope              string
}

func IsAuthenticated(c *fiber.Ctx) error {
	cookie := c.Cookies("jwt")

	token, err := jwt.ParseWithClaims(cookie, &ClaimsWithScope{}, func(token *jwt.Token) (interface{}, error) {
		return []byte(SecretKey), nil
	})

	if err != nil || !token.Valid {
		c.Status(fiber.StatusUnauthorized)
		return c.JSON(fiber.Map{
			"message": "unauthorized",
		})
	}

	payload := token.Claims.(*ClaimsWithScope)
	IsAmbassador := strings.Contains(c.Path(), "/api/ambassador")

	if (payload.Scope == "admin" && IsAmbassador) || (payload.Scope == "ambassador" && !IsAmbassador) {
		c.Status(fiber.StatusUnauthorized)
		return c.JSON(fiber.Map{
			"message": "unauthorized",
		})
	}

	return c.Next()
}


func GenerateJWT(userId uint, scope string) (string, error) {
	payload := ClaimsWithScope{}
	payload.Subject = strconv.Itoa(int(userId)) // 이거랑 string(user.Id)랑 다른가? 보다
	payload.ExpiresAt = time.Now().Add(time.Hour * 24).Unix()
	payload.Scope = scope

	return jwt.NewWithClaims(jwt.SigningMethodHS256, payload).SignedString([]byte(SecretKey))
}

 

7. Redis 활용

docker-compose.yml

redis:
    image: redis:latest
    ports:
      - 6379:6379

 

go에서 Redis를 쉽게 사용할 수 있게하는 패키지

go get github.com/go-redis/redis/v8

 

usage

상품의 전체 정보를 캐싱해서 들고있게 하는게 목적

func ProductsFrontend(c *fiber.Ctx) error {
	var products []models.Product
	ctx := context.Background() // 캐시에 필요한 변수

	result, err := database.Cache.Get(ctx, "products_frontend").Result()

	if err != nil { // 캐싱되어 있지 않을때
		fmt.Println(err.Error())

		database.DB.Find(&products)

		bytes, err := json.Marshal(products) // Marshal로 []byte로 변환
		if err != nil {
			panic(err)
		}

		if errKey := database.Cache.Set(ctx, "products_frontend", bytes, 30*time.Minute).Err(); errKey != nil {
			panic(errKey)
		}
	} else {
		json.Unmarshal([]byte(result), &products)
	}

	return c.JSON(products)
}

'Go' 카테고리의 다른 글

Golang vol.5  (0) 2022.05.05
Golang vol.1 (Getting Start, := = 차이, 함수)  (0) 2022.04.17
Comments