Home [Go] Golang에서의 쿠키
Post
Cancel

[Go] Golang에서의 쿠키

[Go] Golang에서의 쿠키

쿠키란 무엇인가?

쿠키서버클라이언트의 웹 브라우저에 저장하는 정보/파일 입니다. 최대 4kb까지 저장이 가능하며 쿠키의 최대 갯수는 브라우저마다 상이합니다. 상태를 유지를 포함해 여러 활용이 가능하며 클라이언트에게 파일을 저장하게 하므로 서버의 부하를 덜어주는 역할도 합니다.
쿠키key:value쌍을 가지며 두 값 외에도 여러 값을 가집니다. 아래는 go언어에서의 cookie 타입입니다. 몇 개 알아보자면 Path는 쿠키를 전송할 요청 경로를, Domain은 쿠키를 전송할 도메인을 뜻하며 Expires, MaxAge는 쿠키의 만료에 대한 요소인데 뒤에서 다뤄보겠습니다.
2021-04-11 추가
cookie.Secure: https에서만 생성 가능한 쿠키
cookie.HttpOnly: javascript로 접근 불가능

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
type Cookie struct {
    Name  string
    Value string

    Path       string    // optional
    Domain     string    // optional
    Expires    time.Time // optional
    RawExpires string    // for reading cookies only

    // MaxAge=0 means no 'Max-Age' attribute specified.
    // MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0'
    // MaxAge>0 means Max-Age attribute present and given in seconds
    MaxAge   int
    Secure   bool
    HttpOnly bool
    SameSite SameSite // Go 1.11
    Raw      string
    Unparsed []string // Raw text of unparsed attribute-value pairs
}

쿠키 쓰기

고언어에서는 쿠키를 net/http패키지의 SetCookie(w ResponseWriter, cookie *Cookie)함수로 만들 수 있습니다.
ResponseWriter인터페이스와 Cookie구조체를 인자로 전해주어 사용합니다.

1
2
3
4
5
6
7
func createCookie(w http.ResponseWriter, req *http.Request) { 
    http.SetCookie(w, &http.Cookie{
        Name: "name of cookie",
        Value: "value of cookie",
        Path: "/",
    })
}

쿠키 읽기

이렇게 만든 쿠키를 request의 메서드 request.Cookie(name string)를 사용해 읽어줍니다.
반환값으로 쿠키와 에러를 받으며 name을 가진 쿠키가 없을경우 http.ErrNoCookie에러를 반환해줍니다.

1
2
3
4
5
6
7
8
func readCookie(w http.ResponseWriter, req *http.Request) {
    cookie, err := req.Cookie("name of cookie")
    if err == http.ErrNoCookie {
        fmt.Println("there is no cookie named 'name of cookie'")
        return
    }
    fmt.Fprintln(w, "Your cookie: ", cookie)
}

request.Cookies()를 사용해 여러개의 쿠키를 한번에 읽어올 수도 있습니다.

1
2
3
4
5
6
7
8
9
10
11
func readCookie(w http.ResponseWriter, req *http.Request) {
    cookie, err := req.Cookies("name of cookie")
    if err == http.ErrNoCookie {
        fmt.Println("there is no cookie named 'name of cookie'")
        return
    }
    for _, c := range cookie {
        fmt.Fprinln(w,"cookie: ", c)
    }
    fmt.Fprintln(w, "Your cookie: ", cookie)
}

전체 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package main

import (
	"fmt"
	"net/http"
)

func main() {
	http.HandleFunc("/", createCookie)
	http.HandleFunc("/read", readCookie)
	http.Handle("/favicon.ico", http.NotFoundHandler())
	http.ListenAndServe(":8080", nil)
}

func createCookie(w http.ResponseWriter, req *http.Request) { 
    http.SetCookie(w, &http.Cookie{
        Name: "name of cookie",
        Value: "value of cookie",
        Path: "/",
    })
}

func readCookie(w http.ResponseWriter, req *http.Request) {
    cookie, err := req.Cookie("name of cookie")
    if err == http.ErrNoCookie {
        fmt.Println("there is no cookie named 'name of cookie'")
        return
    }
    fmt.Fprintln(w, "Your cookie: ", cookie)
}

코드를 돌려 localhost:8080에 접속을 하면 인덱스 페이지에서 name"name of cookie", value"value of cookie"인 쿠키를 만들게 됩니다. 만들어진 쿠키는 크롬 브라우저에서 F12/Application/Storage/Cookies에서 확인할 수 있습니다. 이렇게 쿠키를 생성해준 뒤 localhost:8080/read로 이동해주면 쿠키의 정보를 제대로 읽어올 수 있는것 을 확인할 수 있습니다.

쿠키 삭제

이렇게 만든 쿠키를 삭제하는 방법에는 두가지가 있습니다. 첫 째는 쿠키의 Expires값을 설정해 주는 것, 둘 째는 쿠키의 MaxAge값을 설정해 주는 것입니다. 이 두가지의 차이점은 expires는 쿠키를 언제까지 지속시킬 지에 대한 시각을 받고, MaxAge는 그 시점부터 얼마나 지속시킬지에 대한 시간을 받습니다. 허나 expiresDeprecated되었다고 하니 MaxAge로 쿠키의 만료시간을 정해주는 게 좋아보입니다.

golang에서 쿠키Expires, MaxAge값을 따로 설정해 주지 않으면 해당 쿠키는 session cookie가 되며 session cookie는 브라우저를 닫을 때 같이 삭제되는 쿠키입니다. 이와 대립하는 쿠키의 종류는 persistent cookie로 항상 유지되는 쿠키를 뜻합니다.

쿠키의 MaxAge값을 -1로 설정해주면 쿠키가 삭제되고 자연수 n으로 설정해주면 n초동안 지속된 뒤 삭제됩니다.
Expires값을 통해 쿠키의 수명을 정해주고 싶다면 time패키지를 사용해주면 되겠다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
func expireCookie(w http.ResponseWriter, req *http.Request) {
    cookie, err := r.Cookie("cookie-name")
    
    if err := nil{
        // 에러처리
    }
    // 1. 쿠키 삭제
    // cookie.MaxAge = -1
    
    // 2. 쿠키를 5초간 지속
    // cookie.MaxAge = 5
    
    // 3. expires 설정, 현재시간으로 부터 1시간 뒤 == 쿠키의 만료시각
    // expiration := time.Now().Add(time.Hour)
    // cookie.Expires = expiration
    
    http.SetCookie(w, cookie)
    http.Redirect(w, req, "/", http.StatusSeeOther)
}
This post is licensed under CC BY 4.0 by the author.

[Go] 정적파일을 서버에 올려보자

[삽질] 자꾸 예상치 못한 301 redirect가 일어날 때...