Для промежуточного программного обеспечения вы можете определить функцию, которая принимает обработчик в качестве аргумента и возвращает другой обработчик в качестве результата.
func sessionMiddleware(h http.HandlerFunc) http.HandlerFunc {
// ...
}
Возвращенный обработчик может store.Get
сеанс, если его нет, returnошибка, если она присутствует, сохранить сеанс в контексте запроса и затем вызвать фактический обработчик.
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)
}
}
Теперь вашим обработчикам все равно нужно будет «получить» значение сеанса из контекста, однако любой обработчик, которыйупакован в 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
}
}
И для регистрации обработчика вы должны сделать:
app.HandleFunc("/", sessionMiddleware(indexHandler))
Если это все еще слишком много повторений кода на ваш вкус, вы можете передать сеанс непосредственно вашим обработчикам, однако вам придется изменить их подпись.
type SessionHandler func(w http.ResponseWriter, r *http.Request, s *session.Session)
Затем обновите свойобработчики.
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
}
}
И вы можете определить часть промежуточного программного обеспечения для типа 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)
}
AnЗатем зарегистрируйте обработчик:
app.Handle("/", SessionHandler(indexHandler))