hen*_*dry 1 session go gorilla
func indexHandler(w http.ResponseWriter, req *http.Request) {
session, err := store.Get(req, sessionName)
if err != nil {
log.WithError(err).Error("bad session")
http.SetCookie(w, &http.Cookie{Name: sessionName, MaxAge: -1, Path: "/"})
}
err = views.ExecuteTemplate(w, "index.html", session.Values)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
Run Code Online (Sandbox Code Playgroud)
我所有的处理程序都使用Gorilla 会话。如何避免store.Get在我的每个处理程序中调用会话,即代码重复?
另一个问题是,是否有更好的方法来为模板提供会话值,而不是一种明确的方式,例如:
err = views.ExecuteTemplate(w, "index.html",
struct {
Session map[interface{}]interface{},
...other handler specific data for the template
}{
session.Values,
...
})
Run Code Online (Sandbox Code Playgroud)
对于中间件,您可以定义一个函数,该函数将处理程序作为参数并返回另一个处理程序作为其结果。
func sessionMiddleware(h http.HandlerFunc) http.HandlerFunc {
// ...
}
Run Code Online (Sandbox Code Playgroud)
返回的处理程序可以store.Get会话,如果它不存在,则返回错误,如果存在,则将会话存储到请求的上下文中,然后调用实际的处理程序。
func sessionMiddleware(h http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
session, err := store.Get(r, sessionName)
if err != nil {
log.WithError(err).Error("bad session")
http.SetCookie(w, &http.Cookie{Name: sessionName, MaxAge: -1, Path: "/"})
return
}
r = r.WithContext(context.WithValue(r.Context(), "session", session))
h(w, r)
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您的处理程序仍然需要从上下文“获取”会话值,但是 sessionMiddleware 包装的任何处理程序都可以假定,在执行时,会话存在于上下文中,因此它可以跳过错误检查。
func indexHandler(w http.ResponseWriter, req *http.Request) {
session := req.Context().Value("session").(*sessions.Session)
err := views.ExecuteTemplate(w, "index.html", session.Values)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
Run Code Online (Sandbox Code Playgroud)
要注册处理程序,您将执行以下操作:
app.HandleFunc("/", sessionMiddleware(indexHandler))
Run Code Online (Sandbox Code Playgroud)
如果这仍然是您喜欢的太多代码重复,您可以将会话直接传递给您的处理程序,但是您必须更改他们的签名。
type SessionHandler func(w http.ResponseWriter, r *http.Request, s *session.Session)
Run Code Online (Sandbox Code Playgroud)
然后更新您的处理程序。
func indexHandler(w http.ResponseWriter, req *http.Request, s *session.Session) {
err := views.ExecuteTemplate(w, "index.html", s.Values)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
Run Code Online (Sandbox Code Playgroud)
您可以将SessionHandler类型上的中间件部分定义为方法。
func (h SessionHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
session, err := store.Get(r, sessionName)
if err != nil {
log.WithError(err).Error("bad session")
http.SetCookie(w, &http.Cookie{Name: sessionName, MaxAge: -1, Path: "/"})
return
}
h(w, r, session)
}
Run Code Online (Sandbox Code Playgroud)
然后要注册处理程序,您将执行以下操作:
app.Handle("/", SessionHandler(indexHandler))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1228 次 |
| 最近记录: |