세션과 쿠키는 웹 애플리케이션에서 사용자의 상태를 유지하고 관리하기 위한 필수적인 도구입니다. 그 이유는 웹의 특성인 HTTP 프로토콜의 비연결성 때문입니다. HTTP는 stabeless(무상태) 프로토콜로, 각 요청 간에 서버가 이전 요청의 상태나 정보를 기억하지 않습니다. 세션과 쿠키는 이러한 한계를 극복하여 지속적인 사용자 경험을 제공하는 역할을 합니다.
정의
세션은 서버 측에서 사용자의 상태를 관리하는 방식으로 웹 서버는 사용자의 고유한 세션 ID를 생성하고, 이 세션 ID를 통해 사용자를 식별하고, 해당 사용자와 관련된 데이터를 서버에서 관리합니다.
역할
세션은 주로 로그인 상태 유지, 사용자 정보 저장 및 관리에 사용, 사용자가 서버와 상호작용하는 동안 지속적인 상태를 유지하는데 사용
저장위치
세션 데이터 자체는 서버에 저장되며, 사용자는 세션 ID만을 클라이언트 측(브라우저 쿠키 등)에 저장합니다. 이 세션 ID를 통해 서버는 어떤 사용자인지 구분합니다.
유효기간
세션은 기본적으로 일정 시간이 지나면 만료되며, 일반적으로 사용자가 웹사이트에서 로그아웃하거나 세션이 타임아웃되면 세션이 종료됩니다.
보안
세션 정보는 서버에 저장되기 때문에 쿠키에 비해 보안성이 더 높다고 할 수 있습니다. 하지만 세션 ID가 탈취되면 세션 하이재킹(Session Hijacking) 등의 공격이 가능할 수 있습니다.
정의
쿠키는 사용자의 웹 브라우저에 저장되는 작은 데이터 조각으로, 웹 서버는 쿠키를 사용해 사용자의 정보를 클라이언트(브라우저) 측에 저장하고, 이후 같은 클라이언트가 웹 서버에 다시 요청을 보낼 때 그 정보를 함께 전송합니다.
역할
쿠키는 주로 사용자 식별, 세션 유지, 사용자 선호 정보 저장 등에 사용
저장위치
클라이언트(사용자의 브라우저)측에 저장
유효기간
쿠키에는 유효기간이 설정될 수 있습니다. 예를 들어, 세션 쿠키(Session Cookie)는 브라우저가 닫힐 때 삭제되고, 영구 쿠키(Persistent Cookie)는 특정 기간 동안 유지될 수 있습니다.
보안
쿠키는 클라이언트 측에서 저장되므로 보안에 주의해야 합니다. 민간함 정보는 쿠키에 직접 저장하지 않으며 보안 상의 문제가 있을 수 있습니다.
저장위치
쿠키는 클라이언트(브라우저)측에 저장되고 세션은 서버에 저장
유효기간
쿠키는 클라이언트에서 유효 기간을 설정할 수 잇으며 브라우저가 닫혀도 유지될 수 있지만, 세션은 주로 서버에서 관리하며 브라우저가 닫히거나 일정 시간 동안 활동이 없으면 만료됩니다.
보안
세션이 서버에 저장되기 때문에 쿠키보다 상대적으로 안전
package main
import (
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/session"
)
var store = session.New() // 세션 미들웨어 초기화
type User struct {
Id string `json:"id"`
Pwd string `json:"pwd"`
}
func main() {
app := fiber.New()
user_route := app.Group("/user")
user_route.Post("/login", func(c *fiber.Ctx) error {
// 세션 초기화
sess, err := store.Get(c)
if err != nil {
return c.Status(500).JSON(fiber.Map{"error": "세션 오류"})
}
user_rf := User{}
// 유저 데이터 파싱
if err := c.BodyParser(&user_rf); err != nil {
return c.Status(400).JSON(fiber.Map{"error": err.Error()})
}
// 유저 데이터 조회
target_user, _ := user.FindIDbyUserID(user_rf.Id)
if target_user.Id == "" {
return c.Status(400).JSON(fiber.Map{"error": "존재하지 않는 ID입니다."})
}
// 비밀번호 복호화
key := []byte("thisis32bitlongpassphraseimusing") // 32바이트 키 (AES-256)
decryptedPwd, err := decryptAES(key, target_user.Pwd)
if err != nil {
return c.Status(400).JSON(fiber.Map{"error": err.Error()})
}
// 비밀번호 검증
if user_rf.Pwd != decryptedPwd {
return c.Status(400).JSON(fiber.Map{"error": "비밀번호가 일치하지 않습니다."})
}
// 세션에 유저 정보 저장
sess.Set("userID", target_user.Id)
// 쿠키 설정 (예: 로그인 유지 토큰)
c.Cookie(&fiber.Cookie{
Name: "auth_token",
Value: "some_token_value", // 여기에는 실제로 생성된 JWT나 세션 토큰을 넣을 수 있음
Expires: time.Now().Add(24 * time.Hour), // 쿠키 만료 시간 설정
HTTPOnly: true, // 클라이언트에서 쿠키 접근 방지
})
// 세션 저장
if err := sess.Save(); err != nil {
return c.Status(500).JSON(fiber.Map{"error": "세션 저장 실패"})
}
return c.JSON("success")
})
app.Listen(":3000")
}
1. 세션 사용
store := session.New()
sess, err := store.Gec(c)
sess.Set("userID", target_user.Id)
sess.Save()
2. 쿠키 사용
c.Cookie(&fiber.Cookie{
Name: "auth_token",
Value: "some_token_value", // 여기에는 실제로 생성된 JWT나 세션 토큰을 넣을 수 있음
Expires: time.Now().Add(24 * time.Hour), // 쿠키 만료 시간 설정
HTTPOnly: true, // 클라이언트에서 쿠키 접근 방지
})
위 코드에서는 auth_token이라는 쿠키를 설정하여 클라이언트에 저장되고 HTTP 요청에 자동으로 포함됩니다. 또, Value에는 인증 토큰이나 세션 ID 같은 값을 저장할 수 있습니다.
추가로 Value에 Uuid를 활용해 식별성 인자를 할당할 수도 있습니다.
uuid, uuidErr := uuid.NewRandom()
c.Cookie(&fiber.Cookie{
Name: "auth_token",
Value: uuid.String(),// 상위 생성된 uuid 할당
Expires: time.Now().Add(24 * time.Hour), // 쿠키 만료 시간 설정
HTTPOnly: true, // 클라이언트에서 쿠키 접근 방지
})