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。
如果没有可重现的示例,“随机”行为很难调试和推理。
关于您的处理程序的一些错误和注意事项。
如果 COOKIE_EXPIRE
环境变量不是整数,您的处理程序会发回错误响应 而不会 return。请注意,您不能在向响应写入任何内容后设置其他 headers(包括 cookie)(http.Error()
会写入响应)。
如果 COOKIE_EXPIRE
是一个整数但为负数或 0
,则 cookie 过期时间(expire
变量)将指向过去并导致正在浏览器中删除 cookie。
如果 cookie 名称无效(COOKIE_NAME
env var),cookie 可能会被静默丢弃(根据 http.SetCookie()
的文档)。
由于你把Secure
设置为true
,注意浏览器中可能设置了cookie,但不安全时不会包含(发送)(HTTP)向您的服务器发出请求。
如果执行模板失败 (tmpl.ExecuteTemplate()
),部分响应可能已经提交,因此您无法发送另一个响应(甚至 http.Error()
)。您要么必须执行指向缓冲区的模板,如果成功,则发送它;或直接将其发送到响应,但如果失败,您将无法在之后进行更正(您最好记录错误以供以后检查)。
我正在尝试设置一个 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。
如果没有可重现的示例,“随机”行为很难调试和推理。
关于您的处理程序的一些错误和注意事项。
如果
COOKIE_EXPIRE
环境变量不是整数,您的处理程序会发回错误响应 而不会 return。请注意,您不能在向响应写入任何内容后设置其他 headers(包括 cookie)(http.Error()
会写入响应)。如果
COOKIE_EXPIRE
是一个整数但为负数或0
,则 cookie 过期时间(expire
变量)将指向过去并导致正在浏览器中删除 cookie。如果 cookie 名称无效(
COOKIE_NAME
env var),cookie 可能会被静默丢弃(根据http.SetCookie()
的文档)。由于你把
Secure
设置为true
,注意浏览器中可能设置了cookie,但不安全时不会包含(发送)(HTTP)向您的服务器发出请求。如果执行模板失败 (
tmpl.ExecuteTemplate()
),部分响应可能已经提交,因此您无法发送另一个响应(甚至http.Error()
)。您要么必须执行指向缓冲区的模板,如果成功,则发送它;或直接将其发送到响应,但如果失败,您将无法在之后进行更正(您最好记录错误以供以后检查)。