Файлы cookie в Golang
Файлы cookie — это способ хранения информации на стороне клиента. Клиентом может быть браузер, мобильное приложение или что-то еще, отправляющее HTTP-запрос. Файлы cookie — это, по сути, файлы, которые хранятся в кэш-памяти вашего браузера. Когда вы просматриваете любой веб-сайт, поддерживающий файлы cookie, в файле cookie сохраняется некоторая информация, связанная с вашими действиями.
Файлы cookie можно отправлять
- В качестве заголовка cookie HTTP-клиента
- В качестве заголовка Set-cookie в ответе HTTP от HTTP-сервера.
Файл cookie в golang представлен, как показано ниже.
https://golang.org/src/net/http/cookie.go
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 Raw string Unparsed []string // Raw text of unparsed attribute-value pairs }
См. https://tools.ietf.org/html/rfc6265 для получения подробной информации о каждом из полей вышеуказанного файла cookie.
Давайте подробно рассмотрим две вещи, связанные с файлами cookie.
- Установить куки в Golang
- Прочитать файл cookie
Установить куки в Golang
Мы уже упоминали, что файл cookie — это всего лишь заголовок. Поэтому для установки определенного файла cookie нам нужно просто установить этот заголовок.
Есть два случая
- Установите cookie при оформлении запроса.
- Установить файл cookie при ответе на входящий запрос
Давайте также рассмотрим каждый из них подробно.
Установите cookie при оформлении запроса.
Это тот случай, когда golang действует как HTTP-клиент. Для добавления файла cookie можно использовать метод AddCookie пакета net/http . Если мы вызовем этот метод для двух разных имен и значений, то и это имя, и значение будут добавлены в результирующий файл cookie.
package main import ( "fmt" "log" "net/http" "net/http/cookiejar" ) var client http.Client func init() { jar, err := cookiejar.New(nil) if err != nil { log.Fatalf("Got error while creating cookie jar %s", err.Error()) } client = http.Client{ Jar: jar, } } func main() { cookie := &http.Cookie{ Name: "token", Value: "some_token", MaxAge: 300, } cookie2 := &http.Cookie{ Name: "clicked", Value: "true", MaxAge: 300, } req, err := http.NewRequest("GET", "http://google.com", nil) if err != nil { log.Fatalf("Got error %s", err.Error()) } req.AddCookie(cookie) req.AddCookie(cookie2) for _, c := range req.Cookies() { fmt.Println(c) } resp, err := client.Do(req) if err != nil { log.Fatalf("Error occured. Error is: %s", err.Error()) } defer resp.Body.Close() fmt.Printf("StatusCode: %d\n", resp.StatusCode) }
Вывод
token=some_token clicked=true StatusCode: 200
В приведенной выше программе HTTP-клиент добавил два файла cookie. Оба этих файла cookie будут отправлены при вызове google.com.
HTTP-клиент в golang также позволяет вам указать CookieJar , который управляет хранением и отправкой файлов cookie при выполнении внешних HTTP-запросов. Как следует из названия, думайте об этом как о банке с печеньем.
HTTP-клиент использует этот jar двумя способами.
- Добавление файлов cookie в эту банку. Вы можете явно добавить файлы cookie в эту банку. Файлы cookie также будут добавлены в банку, если сервер отправит заголовок Set-Cookies в заголовках ответа. Все файлы cookie, указанные в заголовке Set-Cookie, будут добавлены.
- Для просмотра этого jar-файла при выполнении любых внешних HTTP-запросов. Он проверяет этот jar-файл, чтобы узнать, какие файлы cookie ему необходимо отправить для определенного домена.
Для получения дополнительной информации о CookieJar в golang вы можете перейти по этой ссылке https://golangbyexample.com/cookiejar-golang/.
Установить файл cookie при ответе на входящий запрос
Это тот случай, когда golang действует как HTTP-сервер. Структура http.ResponseWriter предоставляет удобный метод установки файла cookie. Ниже приведена подпись метода
func SetCookie(w ResponseWriter, cookie *Cookie)
Этот метод используется для установки файлов cookie в ResponseWriter. Он добавляет заголовок Set-Cookie к заголовкам ответа. Этот заголовок Set-Cookie используется для отправки файла cookie, который должен быть установлен на стороне клиента или браузера. Этот файл cookie затем будет отправлен обратно на сервер, когда клиент сделает последующие вызовы сервера.
Ниже приведена программа для того же самого.
package main import ( "net/http" ) func main() { docHandler := http.HandlerFunc(docHandler) http.Handle("/doc", docHandler) http.ListenAndServe(":8080", nil) } func docHandler(w http.ResponseWriter, r *http.Request) { cookie := &http.Cookie{ Name: "id", Value: "abcd", MaxAge: 300, } http.SetCookie(w, cookie) w.WriteHeader(200) w.Write([]byte("Doc Get Successful")) return }
Запустите вышеуказанную программу, используя
go run main.go
Сервер начнет работать на порту 8080.
Теперь вызовите API localhost:8080/doc из браузера. Сервер отправляет в ответ приведенный ниже Set-Cookie.
Set-Cookie: id=abcd; Max-Age=300
То же самое видно и в заголовках ответа на вызов API. Смотрите скриншот ниже
Прочитать файл cookie в Golang
Структура запроса net/http предоставляет удобный метод чтения определенного файла cookie по его имени. Ниже приведена подпись этого метода. https://golang.org/pkg/net/http/#Request.Cookie
func (r *Request) Cookie(name string) (*Cookie, error)
Чтобы распечатать все файлы cookie, мы можем перебрать метод Cookies структуры http.Request . Для этого мы можем использовать ключевое слово range.
for _, c := range r.Cookies() { fmt.Println(c) }
Ниже приведена программа, иллюстрирующая методы Cookie и Cookies структуры http.Request.
package main import ( "fmt" "log" "net/http" ) func main() { docHandler := http.HandlerFunc(docHandler) http.Handle("/doc", docHandler) http.ListenAndServe(":8080", nil) } func docHandler(w http.ResponseWriter, r *http.Request) { fmt.Println("Cookies in API Call:") tokenCookie, err := r.Cookie("token") if err != nil { log.Fatalf("Error occured while reading cookie") } fmt.Println("\nPrinting cookie with name as token") fmt.Println(tokenCookie) fmt.Println("\nPrinting all cookies") for _, c := range r.Cookies() { fmt.Println(c) } fmt.Println() w.WriteHeader(200) w.Write([]byte("Doc Get Successful")) return }
Запустите приведенную выше программу и выполните приведенный ниже вызов Curl.
curl -X GET localhost:8080/doc --cookie "id=abcd; token=some_token"
Вызов Curl передает две пары имя-значение файла cookie.
- идентификатор = abcd
- токен=некоторый_токен
Это даст результат ниже
Cookies in API Call: Printing cookie with name as token token=some_token Printing all cookies id=abcd token=some_token
Вот как мы печатаем конкретный файл cookie с заданным именем «токен».
tokenCookie, err := r.Cookie("token")
Он печатает, как видно из вывода
token=some_token
Вот как мы печатаем все файлы cookie
for _, c := range r.Cookies() { fmt.Println(c) }
Он выводит обе пары имя-значение файлов cookie, которые мы отправили в вызове Curl.
id=abcd token=some_token
Это все о файлах cookie в Golang. Надеемся, вам понравился урок. Поделитесь, пожалуйста, отзывами в комментариях.