【问题标题】:Want to get session values when client sends new request想要在客户端发送新请求时获取会话值
【发布时间】:2017-12-06 11:27:45
【问题描述】:

我想在客户端创建新请求时获取服务器的会话值。

但是,服务器总是返回 nil。

我不知道这种情况是什么问题。


客户

package main

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

    "github.com/gorilla/mux"
    "github.com/gorilla/securecookie"
    "github.com/gorilla/sessions"
)

var (
    store       *sessions.CookieStore = sessions.NewCookieStore(securecookie.GenerateRandomKey(64))
    session     *sessions.Session
    SessionName = "client"
)

func main() {
    store.Options = &sessions.Options{
        Path:     "/",
        MaxAge:   60 * 15,
        Secure:   false,
        HttpOnly: true,
    }
    router := mux.NewRouter()
    router.HandleFunc("/", cIndex)
    router.HandleFunc("/test", cTest)
    http.ListenAndServe(":7000", router)
}

func cIndex(w http.ResponseWriter, r *http.Request) {
    session, err := store.Get(r, SessionName)
    if err != nil {
        log.Println("cIndex Session Error : ", err.Error())
        return
    }
    session.Values["foo"] = "bar"
    session.Save(r, w)
    w.Header().Set("Location", "http://localhost:8080?foo=bar")
    w.Header().Set("Content-Type", "application/x-www-form-urlencoded")
    w.WriteHeader(http.StatusFound)

}

func cTest(w http.ResponseWriter, r *http.Request) {
    req, err := http.NewRequest("GET", "http://localhost:8080/test", nil)
    if err != nil {
        log.Println("cTest Request Error : ", err.Error())
        return
    }
    req.SetBasicAuth("sample_id", "sample_secret")
    req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
    c := &http.Client{
        Transport: &http.Transport{},
    }
    resp, err := c.Do(req)
    if err != nil {
        log.Println("cTest Response Error : ", err.Error())
        return
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Println("cTest Body Error : ", err.Error())
        return
    }
    log.Println(string(body))
}

服务器

package main

import (
    "encoding/json"
    "log"
    "net/http"

    "github.com/gorilla/mux"
    "github.com/gorilla/securecookie"
    "github.com/gorilla/sessions"
)

var (
    store       *sessions.CookieStore = sessions.NewCookieStore(securecookie.GenerateRandomKey(64))
    session     *sessions.Session
    SessionName = "server"
)

func main() {
    store.Options = &sessions.Options{
        Path:     "/",
        MaxAge:   60 * 15,
        Secure:   false,
        HttpOnly: true,
    }
    router := mux.NewRouter()
    router.HandleFunc("/", sIndex)
    router.HandleFunc("/test", sTest)
    http.ListenAndServe(":8080", router)
}

func sIndex(w http.ResponseWriter, r *http.Request) {
    r.ParseForm()
    v := r.FormValue("foo")
    session, err := store.Get(r, SessionName)
    if err != nil {
        log.Println("sIndex Session Error : ", err.Error())
        return
    }
    session.Values["foo"] = v
    session.Save(r, w)
    w.Header().Set("Location", "http://localhost:7000/test")
    w.Header().Set("Content-Type", "application/x-www-form-urlencoded")
    w.WriteHeader(http.StatusFound)
}

func sTest(w http.ResponseWriter, r *http.Request) {
    session, err := store.Get(r, SessionName)
    if err != nil {
        log.Println("sTest Session Error : ", err.Error())
        return
    }
    v, ok := session.Values["foo"].(string)
    if !ok {
        log.Printf("foo = %v\n", v)
    }
    data := struct {
        Foo string
    }{
        v, // I expected v is bar,but v was nil.
    }

    bytes, err := json.Marshal(data)
    if err != nil {
        log.Println("sTest JSON Error : ", err.Error())
        return
    }
    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(http.StatusOK)
    w.Write(bytes)
}

详情

  1. 客户端通过查询foo=bar向服务器发送请求。

  2. 服务器收到请求并解析。

  3. 服务器在会话中保存查询参数。(我用gorilla/session

  4. 客户端发出*http.Client并向服务器发送新请求。

  5. 服务器接收请求,在会话中加载值,并在响应时设置值。

  6. 客户端收到值bar


在 5 中,我希望服务器可以从 session 中加载值 bar,但 session 值为 nil。

【问题讨论】:

  • @Flimzy 哦,我写代码的时候,没有错误。我认为session, _ := store.Get(r, SessionName) 是正确的,所以我没有写那个。对不起。
  • 我写这些代码时没有出现错误。所以我在写这个问题时省略了err 声明。我认为req, err := http.NewRequest(<method>, <url>, <body>) 语句创建新请求,服务器为请求创建新会话。我为这个问题写了错误的标题。对不起。我的意思是I want to use client.Do() method using existing request 。我的英语水平太差了,所以我无法描述我想要的。我真的很感谢你,Flimzy。谢谢。
  • 有道理。不幸的是,我们不知道...所以最好使用您的实际代码。

标签: session go gorilla


【解决方案1】:

我写了一些代码,它会移动。 方法对吗?

客户

func cTest(w http.ResponseWrite, r *http.Request) {
    serverURL := "http://localhost:8080/test"
    r.Method = http.MethodGet
    r.Host = serverURL  // server
    v, err := url.Parse(serverURL)
    if err != nil {
        log.Println("url parsing error occurred : ", err.Error())
        return
    }
    c := &http.Client{Transport: &http.Transport{}}
    resp, err := c.Transport.RoundTrip(r)
    if err != nil {
        log.Println("client roundtrip error occurred : ", err.Error())
        return
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Println("response body reading error occurred : ", err.Error())
        return
    }
    w.Write(body)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-02
    • 2014-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-24
    • 1970-01-01
    相关资源
    最近更新 更多