如何删除Cookie

19

我写了一个Web应用程序,设置了一个cookie并将其删除。为了清楚起见,看下面的代码片段。

package main

import (
    "fmt"
    "github.com/gorilla/mux"
    "net/http"
    "time"
)

func rootHandler(rw http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(rw, "Hello Foo")

}

func setCookieHandler(rw http.ResponseWriter, r *http.Request) {
    c := &http.Cookie{
        Name:     "storage",
        Value:    "value",
        Path:     "/",
        MaxAge:   0,
        HttpOnly: true,
    }

    http.SetCookie(rw, c)
}

func deleteCookieHandler(rw http.ResponseWriter, r *http.Request) {

    c, err := r.Cookie("storage")
    if err != nil {
        panic(err.Error())
    }
    c.Name = "Deleted"
    c.Value = "Unuse"
    c.Expires = time.Unix(1414414788, 1414414788000)
}

func readCookieHandler(rw http.ResponseWriter, r *http.Request) {

    c, err := r.Cookie("storage")
    if err != nil {
        panic(err.Error())
    }
    fmt.Println(c.Expires)
}

func evaluateCookieHandler(rw http.ResponseWriter, r *http.Request) {

    c, err := r.Cookie("storage")
    if err != nil {
        panic(err.Error())
    }

    if time.Now().After(c.Expires) {
        fmt.Println("Cookie is expired.")
    }
}

func main() {
    mux := mux.NewRouter()
    mux.HandleFunc("/", rootHandler)
    mux.HandleFunc("/cookie", setCookieHandler)
    mux.HandleFunc("/delete", deleteCookieHandler)
    mux.HandleFunc("/read", readCookieHandler)
    mux.HandleFunc("/eval", evaluateCookieHandler)

    http.ListenAndServe(":3000", mux)
}

正如您所看到的,当我访问/cookie位置时,它将按预期设置一个Cookie。然后,当我调用/delete时,应该更改Cookie的名称、值和过期时间。过期时间已更改,但名称和值未更改。

enter image description here

我想删除浏览器中的Cookie以在身份验证系统中退出登录,当用户单击退出登录按钮时删除Cookie。
我还发现了这个链接并遵循其建议,但结果与预期不符。

3个回答

33

如果要删除名为 "storage" 的 cookie,则发送具有相同 cookie 名称的 set-cookie。

deleteCookieHandler() 应该如下所示

c := &http.Cookie{
    Name:     "storage",
    Value:    "",
    Path:     "/",
    Expires: time.Unix(0, 0),

    HttpOnly: true,
}

http.SetCookie(rw, c)

18

MaxAge=0 表示未指定“Max-Age”属性。

MaxAge<0 表示立即删除cookie,相当于“Max-Age:0”

MaxAge>0 表示存在“Max-Age”属性,并以秒为单位给出。

c := &http.Cookie{
    Name:     "storage",
    Value:    "",
    Path:     "/",
    MaxAge:   -1,
    HttpOnly: true,
}

http.SetCookie(rw, c)

实际上,根据 Mozilla 的说法:“cookie 过期的秒数。零或负数会立即使 cookie 过期。如果同时设置了 Expires 和 Max-Age,则 Max-Age 优先级更高。” - 参见这里: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie - dmaixner
2
@dmaixner 您是正确的,根据Cookie规范,但是在处理golang http.Cookie结构时,此答案是正确的:https://golang.org/src/net/http/cookie.go - Kelsin
我可以确认——这对我有效。 - warvariuc

12

Cookie是以名称为键的,所以当您“更改”名称时,实际上是“创建”一个不同的已过期的cookie。

保持名称相同,它应该可以工作,但不要忘记花些时间阅读有关Cookies及其工作原理的文章。


首先,感谢您的回答。您的意思是我只需要设置过期字段吗? - softshipper
过期时间应该足够了。设置一个空值或“短”值有助于减少有效载荷并在某些情况下避免泄露数据。 - Thomas Broyer
1
不要使用“Expires”字段,而是使用负的“Max-Age”。原因是:更合理、流量更少,适用于未同步的时钟。还有一件需要注意的事情:Cookie 不仅按名称键入,还会按路径(和域)键入:在删除期间显式设置它们。 - Volker
我修改了我的代码 https://gist.github.com/kostonstyle/91d8b8fa87628fa300da。考虑到deleteCookieHandler,我将max-age设置为负数,当我调用/delete路径时,max-age保持不变,当我在浏览器中查看cookie时,cookie没有过去的max-age。尝试一下这个例子,你就会知道我在说什么了。 - softshipper
我发现我在deleteCookieHandler函数的结尾忘记加上http.SetCookie(rw, c)。 - softshipper
@Volker,IE8及以下版本不支持Max-Age。http://mrcoles.com/blog/cookies-max-age-vs-expires/ - volker238

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接