随后对 Go Server 的 REST 调用未返回 Cookie

Cookie not being returned with subsequent REST calls to Go Server

我正在探索 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。我的问题在于浏览器似乎没有将令牌附加到 /welcome.html 的 GET 调用上。我可以在浏览器和 welcomeHandler 中确认这一点。

这都是在本地托管的。

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

感谢任何帮助!

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

除非您有明确的理由,否则不要设置域(感谢 Volker 的提醒)。

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