Как работать с cookie в Go: безопасное хранение и управление сессиями
- воскресенье, 2 марта 2025 г. в 00:00:05
Автор статьи: Якушков Федор
Куки (HTTP Cookies) используются для хранения данных на стороне клиента, например, для аутентификации, управления сессиями или персонализации контента. В языке Go работа с куками реализована через стандартную библиотеку net/http, что делает их использование простым и удобным. В этой статье мы разберем основные операции с куками в Go, а также рассмотрим аспекты их безопасности.
Чтобы установить куку в ответе сервера, нужно использовать заголовок Set-Cookie. В Go для этого используется http.SetCookie():
package main
import (
"net/http"
)
func setCookieHandler(w http.ResponseWriter, r *http.Request) {
cookie := &http.Cookie{
Name: "session_id",
Value: "123456",
Path: "/",
HttpOnly: true, // Доступ только через HTTP, защита от XSS
Secure: true, // Только HTTPS
SameSite: http.SameSiteStrictMode, // Защита от CSRF
}
http.SetCookie(w, cookie)
w.Write([]byte("Cookie set!"))
}
func main() {
http.HandleFunc("/set-cookie", setCookieHandler)
http.ListenAndServe(":8080", nil)
}
Этот обработчик устанавливает куку session_id с безопасными параметрами:
HttpOnly: true — запретит доступ к куке из JavaScript (защита от XSS-атак).
Secure: true — кука будет передаваться только по HTTPS.
SameSite: Strict — защита от CSRF-атак.
Куки передаются в заголовке Cookie и доступны в http.Request через метод r.Cookie():
func getCookieHandler(w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie("session_id")
if err != nil {
http.Error(w, "Cookie not found", http.StatusNotFound)
return
}
w.Write([]byte("Cookie value: " + cookie.Value))
}
func main() {
http.HandleFunc("/get-cookie", getCookieHandler)
http.ListenAndServe(":8080", nil)
}
Чтобы удалить куку, нужно установить ее с истекшим сроком:
func deleteCookieHandler(w http.ResponseWriter, r *http.Request) {
cookie := &http.Cookie{
Name: "session_id",
Value: "",
Path: "/",
MaxAge: -1, // Удаление куки
}
http.SetCookie(w, cookie)
w.Write([]byte("Cookie deleted!"))
}
Использование HttpOnly и Secure предотвращает кражу кук через JavaScript (document.cookie) и защищает их от передачи через HTTP.
SameSite защищает от CSRF-атак:
Lax — куки отправляются только при переходах через ссылку.
Strict — куки отправляются только при навигации в рамках одного домена.
None — куки передаются всегда, но только с Secure: true.
Для защиты содержимого кук можно использовать gorilla/securecookie:
import (
"encoding/gob"
"github.com/gorilla/securecookie"
)
var hashKey = []byte("super-secret-key")
var s = securecookie.New(hashKey, nil)
type SessionData struct {
Username string
}
gob.Register(SessionData{})
func setSignedCookie(w http.ResponseWriter) {
value := SessionData{Username: "user123"}
encoded, _ := s.Encode("session", value)
cookie := &http.Cookie{Name: "session", Value: encoded, Path: "/", HttpOnly: true}
http.SetCookie(w, cookie)
}
Работа с куками в Go проста, но требует внимания к безопасности. Использование HttpOnly, Secure, SameSite, а также подпись данных помогают защититься от атак и утечек данных. Если вам нужна безопасная аутентификация, рассмотрите альтернативы вроде JWT или серверных сессий.
Код можно протестировать, запустив сервер на http://localhost:8080 и проверяя установку, получение и удаление кук.