【问题标题】:Cookie not being returned with subsequent REST calls to Go Server对 Go Server 的后续 REST 调用未返回 Cookie
【发布时间】:2020-05-10 09:15:07
【问题描述】:

我正在探索 OAuth2 身份验证并设置一个使用 Github 进行身份验证的服务器。我关注了this example,并且能够让它工作。我想继续提出一些建议并实施基本会话令牌系统并从我的服务器进行 Github 调用,而不是向客户端发送授权令牌。

这是我稍作修改的 /oauth/redirect 处理程序

func oauthRedirectHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Println("/oauth/redirect")

    err := r.ParseForm()
    if err != nil {
        fmt.Fprintf(os.Stdout, "could not parse query: %+v", err)
        w.WriteHeader(http.StatusBadRequest)
    }

    code := r.FormValue("code")

    reqURL := fmt.Sprintf("https://github.com/login/oauth/access_token?client_id=%s&client_secret=%s&code=%s", clientID, clientSecret, code)
    req, err := http.NewRequest(http.MethodPost, reqURL, nil)
    if err != nil {
        fmt.Fprintf(os.Stdout, "could not create HTTP request: %v", err)
        w.WriteHeader(http.StatusBadRequest)
    }

    req.Header.Set("accept", "application/json")

    res, err := httpClient.Do(req)
    if err != nil {
        fmt.Fprintf(os.Stdout, "could not send HTTP request: %+v", err)
        w.WriteHeader(http.StatusInternalServerError)
    }
    defer res.Body.Close()

    var t oAuthAccessResponse
    if err := json.NewDecoder(res.Body).Decode(&t); err != nil {
        fmt.Fprintf(os.Stdout, "could not parse JSON response: %+v", err)
        w.WriteHeader(http.StatusBadRequest)
    }

        newSession := sessionTracker{
        AccessToken: accessToken,
        TimeOut:     time.Now().Add(time.Minute * 15),
    }

    sessionToken := uuid.New().String()

    sessionTrackerCache[sessionToken] = newSession

    http.SetCookie(w, &http.Cookie{
        Name:    sessionTokenConst,
        Value:   sessionToken,
        Expires: newSession.TimeOut,
        Domain:  "localhost",
    })

    http.Redirect(w, r, "/welcome.html", http.StatusFound)
}

它会重定向到带有包含我的 SessionToken id 的附加 cookie 的欢迎页面。

这是我的welcomeHandler

func welcomeHandler(w http.ResponseWriter, req *http.Request) {
    fmt.Println("/welcome")

    cookie, err := req.Cookie(sessionTokenConst)
    if err != nil {
        fmt.Fprintf(os.Stdout, "no cookie attached: %+v", err)
        w.WriteHeader(http.StatusBadRequest)
        return
    } 

    dat, err := ioutil.ReadFile("./public/welcome.html")
    if err != nil {
        fmt.Fprintf(os.Stdout, "could not read welcome page: %+v", err)
        w.WriteHeader(http.StatusInternalServerError)
    }

    fmt.Fprintf(w, string(dat))
}

观察浏览器的网络选项卡,我通过 Github 进行身份验证,我的服务器能够看到授权令牌。 oauthRedirectHandler 末尾的重定向响应包含带有 SessionID 的 cookie。我的问题在于浏览器似乎没有将 GET 调用中的令牌附加到 /welcome.html。我可以在浏览器和welcomeHandler 中确认这一点。

这一切都在本地托管。

我不确定这是否是我的服务器、浏览器的问题,或者我是否理解在 cookie 过期日期错误之前浏览器会将 cookie 应用于任何未来的客户端请求。

感谢任何帮助!

【问题讨论】:

  • 与您的问题无关,但请记住,您拥有WriteHeader 以向浏览器返回错误代码的所有地方,因为您不是来自您的处理程序的returning,您的处理程序继续运行 - 可能导致更多错误,并可能导致多次 WriteHeader 调用,这本身就是一个错误。
  • @Adrian 感谢您的提醒。我注意到我遇到的其他问题,并且已经更正了。

标签: go cookies oauth-2.0 session-cookies setcookie


【解决方案1】:

浏览器默认 cookie 路径为请求路径。将路径设置为“/”以使 cookie 在整个站点中可用。

除非您有明确的理由,否则请勿设置域(感谢 Volker 注意到这一点)。

http.SetCookie(w, &http.Cookie{
    Name:    sessionTokenConst,
    Value:   sessionToken,
    Path:    "/", // <--- add this line
    Expires: newSession.TimeOut,
    // Domain:  "localhost",  <-- Remove this line
})

【讨论】:

  • 并且不要设置域。
猜你喜欢
  • 2014-06-06
  • 2015-05-31
  • 2021-08-26
  • 2015-12-28
  • 1970-01-01
  • 2015-01-28
  • 2015-12-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多