登录
首页 >  Golang >  Go问答

Go 的会话中间件?

来源:stackoverflow

时间:2024-04-22 16:03:37 224浏览 收藏

从现在开始,努力学习吧!本文《Go 的会话中间件?》主要讲解了等等相关知识点,我会在golang学习网中持续更新相关的系列文章,欢迎大家关注并积极留言建议。下面就先一起来看一下本篇正文内容吧,希望能帮到你!

问题内容

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
    }
}

我的所有处理程序都使用 gorilla 会话。如何避免 store.getting 我的每个处理程序中的会话,即代码重复?

另一个问题,是否有更好的方法为模板提供会话值,而不是像这样的显式方法:

err = views.ExecuteTemplate(w, "index.html",
    struct {
        Session map[interface{}]interface{},
        ...other handler specific data for the template
    }{
        session.Values,
        ...
    })

代码示例源自https://github.com/kaihendry/internal-google-login


解决方案


对于中间件,您可以定义一个函数,该函数将处理程序作为参数并返回另一个处理程序作为其结果。

func sessionmiddleware(h http.handlerfunc) http.handlerfunc {
    // ...
}

返回的处理程序可以 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)
    }
}
现在,您的处理程序仍然需要从上下文中“获取”会话值,但是由 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)
}

然后注册处理程序,您将执行以下操作:

app.Handle("/", SessionHandler(indexHandler))

理论要掌握,实操不能落!以上关于《Go 的会话中间件?》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>