4

我正在使用 Go 制作一个简单的 Web 应用程序,gorilla 用于会话和路由,mustache 用于模板。我在登录时遇到问题,我相信这是 IE 接受 cookie 的问题。该问题仅在 Internet Explorer 中出现,但在其他情况下登录在 Chrome 中完美运行。这是我的代码:

func main() {
    r := mux.NewRouter()
    r.HandleFunc("/performance", Index)
    r.HandleFunc("/performance/login", Login)
    log.Fatal(http.ListenAndServe(":5901", r))
}

func Index(w http.ResponseWriter, r *http.Request) {
    session, _ := store.Get(r, "performance")
    if session.Values["username"] == nil {
        http.Redirect(w, r, "/performance/login", http.StatusSeeOther)
    }
    dict := session.Values
    fmt.Fprintf(w, mustache.RenderFileInLayout("templates/index.html", "templates/basepage.html", dict))
}

func Login(w http.ResponseWriter, r *http.Request) {
    if r.Method == "POST" {
        results := 0
        r.ParseForm()
        u := r.FormValue("username")
        pass := r.FormValue("password")
        p := PassEncrypt(pass)
        q := map[string]string{}
        rows, err := db.Query("SELECT username, name, title FROM user WHERE (username=$1) AND (password=$2)", u, p)
        if err != nil {
            log.Fatal(err)
        }
        for rows.Next() {
            var username string
            var name string
            var title string
            if err := rows.Scan(&username, &name, &title); err != nil {
                log.Fatal(err)
            }
            q["username"] = username
            q["name"] = name
            q["title"] = title
            results++
        }
        if results > 0 {
            session, _ := store.Get(r, "performance")
            session.Options = &sessions.Options{
                MaxAge: 900,
            }
            session.Values["username"] = q["username"]
            session.Values["name"] = q["name"]
            session.Values["title"] = q["title"]
            session.Save(r, w)
            http.Redirect(w, r, "/performance", http.StatusSeeOther)
        } else {
            http.Redirect(w, r, "/performance/login", http.StatusSeeOther)
        }
    } else {
        fmt.Fprintf(w, mustache.RenderFileInLayout("templates/login.html", "templates/basepage.html", nil))
    }
}

使用 IE 登录时,用户被重定向回登录页面,因为会话值“用户名”为 nil,而在 Chrome 中,用户名被正确定义并提供索引页面。出于某种原因,IE 不接受 cookie,但我更改了 IE 中的所有设置以允许来自任何站点的 cookie。我是否需要更改其中一个 cookie 选项或在 cookie 中添加除“MaxAge”以外的内容以供 IE 接受?提前致谢。

4

2 回答 2

3

You probably need to define the cookie's path in your options. The following options struct should do the trick:

session.Options = &sessions.Options{
    Path: "/performance",
}

Said option limits the cookie's availability to the given path, for the whole page use "/".

Note that the max-age setting is not supported by IE:

[...] Internet Explorer (including IE8) does not attempt to support any RFC for cookies. WinINET (the network stack below IE) has cookie implementation based on the pre-RFC Netscape draft spec for cookies. This means that directives like max-age, versioned cookies, etc, are not supported in any version of Internet Explorer.

By the way, you don't need a MaxAge for session cookies (from the IE manual on cookies):

(expires=date;)
    If you set no expiration date on a cookie, it expires when the browser 
    closes. If you set an expiration date, the cookie is saved across browser 
    sessions. If you set an expiration date in the past, the cookie is deleted. 
    Use Greenwich Mean Time (GMT) format to specify the date.

This should be the case for all major browsers.

于 2013-06-11T23:54:50.650 回答
1

我有一个类似的问题,即使用 Gorilla 会话在 IE9 上注销不起作用(尽管登录工作正常)。

我最终发现 IE 正在缓存对我的 API 端点的响应并将缓存的(304 未修改)API 响应发送到客户端,即使 cookie 值发生变化。

强制 API 端点永远不会被缓存解决了这个问题:

w.Header().Set("Expires", "Tue, 03 Jul 2001 06:00 GMT")
w.Header().Set("Last-Modified", "{now} GMT")
w.Header().Set("Cache-Control", "max-age=0, no-cache, must-revalidate, proxy-revalidate")
于 2015-06-03T17:06:18.237 回答