Cookie 随机设置

Cookie sets randomly

我正在尝试设置一个 Cookie,但有时可以,有时却不能。没有明显的规律。

func quoteGetHandler(w http.ResponseWriter, req *http.Request) {
    parts := strings.Split(req.URL.Path, "/")
    csrfToken := uniuri.NewLen(32)
    exp, err := strconv.Atoi(os.Getenv("COOKIE_EXPIRE"))  //5
    if err != nil {
        http.Error(w, whereami.WhereAmI()+err.Error(), http.StatusInternalServerError)
    }
    expire := time.Now().Add(time.Duration(exp) * time.Minute)
    cookie := http.Cookie{
        Name:     os.Getenv("COOKIE_NAME"), //csrf_token
        Value:    csrfToken, //string
        Path:     "/",
        Expires:  expire,
        HttpOnly: true,
        Secure:   true,
        MaxAge:   0,
        Domain:   os.Getenv("DOMAIN")} //<--example.com
    http.SetCookie(w, &cookie)
    tmp := htmlTags["quote"]
    tmp.CsrfToken = csrfToken
    if 2 < len(parts) && parts[2] != "" {
        tmp.Param = parts[2]
    }
    htmlTags["quote"] = tmp
    err = tmpl.ExecuteTemplate(w, siteType+"quote", htmlTags["quote"])
    if err != nil {
        http.Error(w, whereami.WhereAmI()+err.Error(), http.StatusInternalServerError)
    }
}

这发生在 Chrome、FF、Bravo、Safari 上。

协议为 https。

如果没有可重现的示例,“随机”行为很难调试和推理。

关于您的处理程序的一些错误和注意事项。

  1. 如果 COOKIE_EXPIRE 环境变量不是整数,您的处理程序会发回错误响应 而不会 return。请注意,您不能在向响应写入任何内容后设置其他 headers(包括 cookie)(http.Error() 会写入响应)。

  2. 如果 COOKIE_EXPIRE 是一个整数但为负数或 0,则 cookie 过期时间(expire 变量)将指向过去并导致正在浏览器中删除 cookie。

  3. 如果 cookie 名称无效(COOKIE_NAME env var),cookie 可能会被静默丢弃(根据 http.SetCookie() 的文档)。

  4. 由于你把Secure设置为true,注意浏览器中可能设置了cookie,但不安全时不会包含(发送)(HTTP)向您的服务器发出请求。

  5. 如果执行模板失败 (tmpl.ExecuteTemplate()),部分响应可能已经提交,因此您无法发送另一个响应(甚至 http.Error())。您要么必须执行指向缓冲区的模板,如果成功,则发送它;或直接将其发送到响应,但如果失败,您将无法在之后进行更正(您最好记录错误以供以后检查)。