英文:
Cookie sets randomly
问题
我正在尝试设置一个Cookie,有时它能正常工作,有时却不能。没有明显的模式。
这个问题发生在Chrome、FF、Bravo和Safari浏览器上。
协议是https。
英文:
I am attempting to set a Cookie and sometimes it works and other times it does not. There is no obvious pattern.
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)
}
}
This happens on Chrome ,FF, Bravo, Safari.
The protocol is https.
答案1
得分: 2
“随机”行为在没有可重现的示例的情况下很难进行调试和推理。
关于您的处理程序的一些错误和注意事项。
1)如果COOKIE_EXPIRE
环境变量不是整数,您的处理程序会发送错误响应并且不返回。请注意,在向响应中写入任何内容之后,您无法设置其他标头(包括cookie)(http.Error()
会写入响应)。
2)如果COOKIE_EXPIRE
是一个整数,但是为负数或0
,则cookie的过期时间(expire
变量)将指向过去,并导致浏览器中的cookie被删除。
3)如果cookie名称无效(COOKIE_NAME
环境变量),则cookie可能会被静默丢弃(根据http.SetCookie()
的文档)。
4)由于您将Secure
设置为true
,请注意,该cookie可能会在浏览器中设置,但在向您的服务器发出不安全(HTTP)请求时不会包含(发送)该cookie。
5)如果执行模板失败(tmpl.ExecuteTemplate()
),则部分响应可能已经被提交,因此您无法发送另一个响应(甚至不是http.Error()
)。您可以将模板执行到缓冲区中,如果成功,则发送它;或者直接将其发送到响应中,但如果失败,则无法进行更正(您能做的最好的是记录错误以供以后检查)。
英文:
"Random" behavior is hard to debug and reason about without a reproducible example.
Some errors and notes regarding your handler.
-
If the
COOKIE_EXPIRE
env var is not an integer, your handler sends back an error response and does not return. Note that you can't set other headers (including cookies) after you write anything to the response (http.Error()
does write to the response). -
If the
COOKIE_EXPIRE
is an integer but is negative or0
, the cookie expiration (expire
variable) will point to the past and will result in the cookie being deleted in the browser. -
If cookie name is invalid (
COOKIE_NAME
env var), the cookie may be silently discarded (as per the doc ofhttp.SetCookie()
). -
Since you set
Secure
totrue
, note that the cookie may be set in the browser, but it will not be included (sent) when insecure (HTTP) requests are made to your server. -
If executing the template fails (
tmpl.ExecuteTemplate()
), some of the response may already be committed, so you can't send another response (not evenhttp.Error()
). You either have to execute the template directed into a buffer, and if it succeeds, then send it; or send it directly to the response, but if it fails, you can't make corrections afterwards (best you can do is log the error for later inspection).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论