Читать cookie в Go

Я развертываю простой HTTP-сервер и простой HTTP-клиент в Go. Я безуспешно пытался прочитать значение cookie от клиента (я получаю пустое значение), даже если на сервере установлено значение, которое я вижу. Как я могу прочитать значение cookie на стороне клиента (т.е. отправить дальнейшие запросы, включив cookie, который я получил)?

Код сервера

package main

import (
    "log"
    "math/rand"
    "net/http"
    "strconv"
    "strings"
    "time"
)

var SERVER_PORT string = ":8080"

func setCookie(w http.ResponseWriter, username string){
    cookieValue := username + ":" + (username+strconv.Itoa(rand.Intn(100000000)))
    //expiration := time.Now().Add(365 * 24 * time.Hour)
    expiration := time.Now().Add(20 * time.Second)
    cookie := http.Cookie{Name:"SessionID", Value: cookieValue, Expires: expiration}
    http.SetCookie(w, &cookie)
    log.Print(cookie)
}

func sayHello(w http.ResponseWriter, r* http.Request) {
    username := r.URL.Path
    username = strings.TrimPrefix(username, "/")
    setCookie(w,username)
    message := "Hello " + username
    w.Write([]byte(message))
}

func ReadCookieServer(w http.ResponseWriter, req *http.Request) {
    // read cookie
    var cookie,err = req.Cookie("SessionID")
    if err == nil {
        var cookievalue = cookie.Value
        w.Write([]byte(cookievalue))
    }
}

func main() {
    http.HandleFunc("/", sayHello)
    http.HandleFunc("/readcookie", ReadCookieServer)
    if err := http.ListenAndServe(SERVER_PORT, nil); err != nil {
        panic(err)
    }
}

Код клиента

package main

import (
    "io/ioutil"
    "log"
    http "net/http"
)

var serverName string = "http://localhost"
var serverPort string = ":8080/"

func MakeRequest() {
    var username string = "blabla"
    resp, err := http.Get(serverName + serverPort + username)
    if err != nil {
        log.Fatalln(err)
    }
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }
    log.Println(string(body))
}

func Readcookie() {
    resp, err := http.Get(serverName + serverPort + "readcookie")
    if err != nil {
        log.Fatalln(err)
    }
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }
    log.Println(string(body))
}

func main() {
    MakeRequest()
    Readcookie()
}

@Flimzy Когда клиент отправляет запрос на сервер, в этом случае клиент должен увидеть ответ и cookie, которые он получил от сервера. Я не понимаю, почему я не вижу его на стороне клиента.

CipherX 27.10.2018 16:25

Какой делать вы видите на клиенте? Что вы ожидали увидеть вместо этого?

Flimzy 27.10.2018 16:26

У вас есть cookie в первом запросе MakeRequest клиентского кода. Второй запрос от клиентского кода Readcookie не предоставляет никаких файлов cookie для сервера.

Зелёный 27.10.2018 16:27

@Flimzy Я вижу только «Привет» + имя пользователя. Я хотел бы увидеть содержимое файлов cookie, которые я получил с сервера.

CipherX 27.10.2018 16:34

Где вы пытаетесь прочитать cookie? Все, что я вижу, вы делаете, это сбрасываете тело ответа.

Flimzy 27.10.2018 16:37
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
0
5
5 148
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вы хотите прочитать cookie из HTTP-запроса, вы делаете это с помощью метода Cookies. Пример:

func Readcookie() {
    resp, err := http.Get(serverName + serverPort + "readcookie")
    if err != nil {
        log.Fatalln(err)
    }
    for _, cookie := range resp.Cookies() {
        if cookie.Name == "SessionID" {
            log.Println("Cookie: ", cookie.Value)
        }
    }
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }
    log.Println(string(body))
}

Для достижения вашей более крупной цели - управления сеансом для последующих HTTP-запросов, просто создайте экземпляр файла cookie на своем HTTP-клиенте. Пример:

var client *http.Client

func init() {
    jar, err := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
    if err != nil {
        panic(err)
    }
    client = &http.Client{Jar: jar}
}

Затем используйте этот клиент (а не по умолчанию) для своих последующих запросов:

func Readcookie() {
    resp, err := client.Get(serverName + serverPort + "readcookie")
    if err != nil {
        log.Fatalln(err)
    }
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }
    log.Println(string(body))
}   

«не работает» - не полезная формулировка проблемы. С какими проблемами вы столкнулись? Что вы ожидали увидеть вместо этого?

Flimzy 28.10.2018 17:34

Когда я импортирую "golang.org/x/net/publicsuffix", я получаю сообщение об ошибке во время импорта (вероятно, его нет в репо)

CipherX 28.10.2018 17:38

Значит, вы пытались установить этот пакет?

Flimzy 28.10.2018 17:44

Другие вопросы по теме