Cookie 已设置但未检测到

Posted

技术标签:

【中文标题】Cookie 已设置但未检测到【英文标题】:Cookie set and not detected 【发布时间】:2021-12-25 04:17:08 【问题描述】:

我正在构建一个将使用许多路由的网站,因此我不想要单独的处理程序。我的解决方案是遍历端点列表。 当我这样做时,设置了一个 cookie 但未检测到。下面的代码可以复制粘贴,只需cmets/uncomment两个路由系统即可。

package main

import (
    "fmt"
    "html/template"
    "log"
    "net/http"

    "github.com/gorilla/handlers"
    "github.com/gorilla/mux"
)

var tmpl *template.Template
const testCookieName = "testCookieName"
const testCookievalue = "testCookievalue"

func main()
    port :=":8088"
    router := mux.NewRouter()
    router.Use(middlewareSetCookie)
    router.Use(middlewareCheckCookies)//no cookie sends page to /cookie for an error msg
    router.Use(middlewareNoWWW)
    router.Use(middlewareHeaders)

    //Using individual routes works as expected and a cookie is set and detected.
/*
    router.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) 
        err := tmpl.ExecuteTemplate(w, "index", "")
        if err != nil 
            http.Error(w, err.Error(), http.StatusInternalServerError)
        
    )

    router.HandleFunc("/cookie", func(w http.ResponseWriter, r *http.Request) 
        err := tmpl.ExecuteTemplate(w, "cookie", "")
        if err != nil 
            http.Error(w, err.Error(), http.StatusInternalServerError)
        
    )
*/


    //Given the number of routes I need I have to use a loop to iterate over all to keep the code base maintanable 
    //The cookie is set but not detected in the code below
/**/
    pages := make(map[string]string)
    pages["/"] = "index"
    pages["/cookie"] = "cookie"

    for k, v :=range pages
            router.HandleFunc(k, func(w http.ResponseWriter, r *http.Request) 
            err := tmpl.ExecuteTemplate(w, v, "")
            if err != nil 
                http.Error(w, err.Error(), http.StatusInternalServerError)
            
        )
    

    
    var err error
    tmpl, err = template.ParseGlob("views/*")
    if err != nil 
        panic(err.Error())
    

    router.PathPrefix("/").HandlerFunc(func(res http.ResponseWriter, req *http.Request) 
        http.FileServer(http.Dir("./static/")).ServeHTTP(res, req)
    )

    fmt.Println("Server running on localhost" + port)

    err = http.ListenAndServe(port, handlers.CompressHandler(router))
    if err != nil 
        log.Fatal(err)
    


func middlewareNoWWW(next http.Handler) http.Handler 
    fmt.Println("middlewareNoWWW")
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) 
        if r.Host[0:4] == "www." 
            target := "http://" + r.Host[4:]
            http.Redirect(w, r, target, 301)
        
        next.ServeHTTP(w, r)
    )


func middlewareHeaders(next http.Handler) http.Handler 
    fmt.Println("middlewareHeaders")
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) 
        w.Header().Set("Cache-Control", "max-age=2592000") // 30 days
        w.Header().Set("Content-Encoding", "gzip")
        w.Header().Set("Strict-Transport-Security", "max-age=63072000; includeSubDomains; preload")
        next.ServeHTTP(w, r)
    )


func middlewareSetCookie(next http.Handler) http.Handler 
    fmt.Println("middlewareSetCookie")
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) 
        c, err := r.Cookie(testCookieName)
        if err != nil || c.Value != testCookievalue 
            cookie := http.Cookie
                Name:     testCookieName,
                Value:    testCookievalue,
                Path:     "/",
                HttpOnly: true,
                MaxAge:   0,
                Domain:   "localhost"

            http.SetCookie(w, &cookie)
        
        next.ServeHTTP(w, r)
    )


func middlewareCheckCookies(next http.Handler) http.Handler 
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) 
        fmt.Println("middlewareCheckCookies")
        fmt.Println(r.URL.String())

        c, err := r.Cookie(testCookieName)
        if err != nil || c.Value != testCookievalue 
            redirectURL := "/cookie"
            if r.URL.String() != redirectURL 
                http.Redirect(w, r, redirectURL, http.StatusTemporaryRedirect)
                return
            
        
        next.ServeHTTP(w, r)
    )

./views/cookie.html

define "cookie"no cookie set<a href="/">index</a>end

./views/index.html

define "index"<a href="/">index</a>end

有解决这个问题的线索吗?

【问题讨论】:

在调用 http.Redirect 后,有几个地方函数会继续正常流程。写入重定向标头后从函数返回。 添加了退货但问题仍然存在。 修复所有对 http.Redirect 的调用的问题。尝试从 cookie 中删除域。另请注意,SetCookie 设置响应标头,Request.Cookie 获取请求标头。在以后的请求之前,您不能期望看到 SetCookie 的结果。 我刚刚测试,我可以看到 cookie 值,我错过了什么吗? ibb.co/BsLmjF2 您在任何时候是否有不同的(例如,不是临时的)重定向代码?对我来说,这听起来很像您在某个时候进行了永久重定向,现在您的浏览器已经缓存了该响应。 【参考方案1】:

您的代码的问题在于它为处理函数构建了糟糕的闭包。如果您不使用无法控制的变化(在这种情况下通过循环)变量来构建闭包,这将有所帮助。您可以添加以下代码行来解决问题:

    for k, v := range pages 
        k, v := k, v // <-- this line

这样,每个处理函数都会有自己的一组外部变量。

说实话,我真的不明白你最初的问题是什么。这是什么意思——“一个 cookie 是……未检测到”?

【讨论】:

以上是关于Cookie 已设置但未检测到的主要内容,如果未能解决你的问题,请参考以下文章

Chrome Beta 问题:尽管 SameSite cookie 设置为“无”且安全,但未收到第三方 cookie

在响应标头中使用 apollo,cookie 但未设置

如何检测是不是设置了 httpOnly cookie

ComboBox 已设置 DataSource 但未显示任何项目

RestKit 映射结果已填充,但未设置核心数据实体

iOS 框架 - 已加载 nib 但未设置视图出口