会话的最佳实践(大猩猩/会话)

cla*_*rkk 9 session go

在开始使用golang中的会话之前,我需要回答一些问题

会话示例

import "github.com/gorilla/sessions"

var store = sessions.NewCookieStore([]byte("33446a9dcf9ea060a0a6532b166da32f304af0de"))

func Handler(w http.ResponseWriter, r *http.Request){
    session, _ := store.Get(r, "session-name")

    session.Values["foo"] = "bar"
    session.Values[42] = 43
    session.Save(r, w)

    fmt.Fprint(w, "Hello world :)")
}

func main(){
    store.Options = &sessions.Options{
        Domain:     "localhost",
        Path:       "/",
        MaxAge:     60 * 15,
        Secure:     false,
        HttpOnly:   true,
    }
}
Run Code Online (Sandbox Code Playgroud)

Q1:

是否可以在同一个域中使用不同的名称添加多个会话?

session1, _ := store.Get(r, "session-name-1")
session2, _ := store.Get(r, "session-name-2")
Run Code Online (Sandbox Code Playgroud)

您何时需要在同一个域上进行多个会话?

Q2:

从会话中获取变量的最佳做法是什么?my_session_var = session.Values ["foo"]

Q3:

如何检查会话是否正确保存?如果同时访问mapset和get变量?

更新

package main

import (
    "github.com/gorilla/sessions"
)

var (
    store = sessions.NewCookieStore([]byte("33446a9dcf9ea060a0a6532b166da32f304af0de"))
)

type handler func(w http.ResponseWriter, r *http.Request, s *sessions.Session)

func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request){
    session, _ := store.Get(r, "session-name")

    h(w, r, session)
}

func Handler_404(w http.ResponseWriter, r *http.Request, s *sessions.Session){
    fmt.Fprint(w, "Oops, something went wrong!")
}
Run Code Online (Sandbox Code Playgroud)

错误

# command-line-arguments
.\mux.go:101: cannot convert Handler_404 (type func(http.ResponseWriter, *http.Request, *sessions.Session)) to type http.HandlerFunc
Run Code Online (Sandbox Code Playgroud)

Von*_*onC 5

文章" GO的HTTP处理程序的基本扩展 "(Simon Whitehead)显示了定义会话的位置和时间的示例.
而不是在Handler自身中执行它,并且在定义其他处理程序时必须复制大量代码.

使用命名类型,您可以定义Handler所需:

type handler func(w http.ResponseWriter, r *http.Request, db *mgo.Database)
Run Code Online (Sandbox Code Playgroud)

(在您的情况下,它将是一个大猩猩会话而不是一个mgo会话或数据库)

init()函数可以处理会话创建(这里是mgo会话,但其他框架会话的想法是相同的)

func init() {
    session, err = mgo.Dial("localhost")

    if err != nil {
        log.Println(err)
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以确保这个函数类型(' handler')确实尊重这个ServeHTTP()函数,照顾:

  • 会话管理(克隆/关闭)
  • 调用您的实际处理程序(可已经不仅仅是更多的参数wr)

    func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
        s := session.Clone()
        defer s.Close()
    
        h(w, r, s.DB("example"))
    }
    
    Run Code Online (Sandbox Code Playgroud)

然后你可以定义你的实际Handler(再次,超过wr):

func myHandler(w http.ResponseWriter, r *http.Request, db *mgo.Database) {
    var users []user

    db.C("users").Find(nil).All(&users)

    for _, user := range users {
        fmt.Fprintf(w, "%s is %d years old", user.Name, user.Age)
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以在服务器中使用该处理程序:

func main() {
    mux := http.NewServeMux()
    mux.Handle("/", handler(myHandler))
    http.ListenAndServe(":8080", mux)
}
Run Code Online (Sandbox Code Playgroud)

我们的想法是将"管道"限制在main()最低限度,同时Handler拥有更多参数(包括您的会话).
这允许你使用Handlers非常少的管道,main()只保留不同路径的声明(而不是初始化会话和处理程序)