首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >按手编写中间件

按手编写中间件
EN

Stack Overflow用户
提问于 2013-11-05 08:36:10
回答 1查看 955关注 0票数 5

我希望从我的处理程序中提取一些重复的逻辑,并将其放入某些处理程序中间件中:特别是CSRF检查、检查现有会话值(即用于auth或预览页)等。

我读过关于这个的几篇文章,但是很多例子都集中在每台服务器的中间件(包装http.Handler)上:我有一组更小的处理程序,需要中间件。我的大多数其他页面没有,因此,如果我能够避免检查会话/等等,那么这些请求越好越好。

到目前为止,我的中间件通常如下所示:

代码语言:javascript
运行
复制
func checkCSRF(h http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // get the session, check/validate/create the token based on HTTP method, etc.
        // return HTTP 403 on a failed check
        // else invoke the wrapped handler h(w, r)
    }
}

但是,在许多情况下,我希望将一个变量传递给包装处理程序:一个生成的CSRF令牌传递给模板,或者一个包含表单数据的结构--一个中间件在用户点击/preview/ URL之前检查会话中是否存在一些已保存的表单数据,否则它会将它们重定向出去(因为它们没有什么可预览的!)。

我希望将该结构传递给包装处理程序,以保存必须复制session.Get/type断言/错误检查逻辑(我刚刚在中间件中编写的逻辑)。

我可以写这样的东西:

代码语言:javascript
运行
复制
type CSRFHandlerFunc func(w http.ResponseWriter, r *http.Request, t string)

..。然后编写如下中间件:

代码语言:javascript
运行
复制
func csrfCheck(h CSRFHandlerFunc) http.HandlerFunc {
     return func(w http.ResponseWriter, r *http.Request) {
        // get the session, check/validate/create the/a token based on HTTP method, etc.
        // return HTTP 403 on a failed check
        // else invoke the wrapped handler and pass the token h(w, r, token)
    }

..。但这提出了几个问题:

  • 这是实现每个处理程序中间件和传递每个请求变量的明智方法吗?
  • 在测试这一点之前(不要访问我的开发机器!),如果我需要用多个中间件包装处理程序,我想我可以只使用r.HandleFunc("/path/preview/", checkCSRF(checkExisting(previewHandler)))吗?我在这里看到的问题是,中间件现在是紧密耦合的:包装的中间件现在需要接收并传递来自外部中间件的变量。这使得扩展http.HandlerFunc变得更棘手/更复杂。
  • 大猩猩/背景是否更适合这里,并允许我避免编写2-3个自定义处理程序类型(或者泛型处理程序类型)--如果是这样,我将如何使用它?或者我可以实现自己的“上下文”映射(并遇到并发访问的问题)。

在可能的情况下,我试图避免落入“不要被捕捉到编写库”的陷阱中,但是中间件是我可能在项目后期添加/构建的东西,我希望第一次“正确”。

如能就此提供一些指导,将不胜感激。到目前为止,Go在编写web应用程序方面做得很好,但在这个阶段还没有太多的例子,因此,我还有点依赖于它。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-11-05 13:17:26

如果我正确理解了您的问题,您正在寻找一种向中间件传递附加参数的方便方法,对吗?

现在,定义这些参数是很重要的。它们可能是中间件的一些配置值--这些值可以在构建Handler类型时设置)。而不是NewMyMiddleware(MyHandler),而是NewMyMiddleware(MyHandler, "parameter"),这里没有问题。

但在您的情况下,您似乎希望传递每个请求参数,比如CSRF令牌。将这些信息传递到处理程序函数中将修改其签名,并且它将偏离标准的Handler[Func]接口。在这种情况下,中间件更紧密地耦合是正确的。

您自己也提到了解决方案--在我看来,上下文映射,是一个可行的工具。这并不是说很难自己编写一个--您基本上需要一个map[*http.Request]interface{}和一个RWMutex来实现安全的并发访问。不过,简单地使用gorilla/context就足够了--它似乎是一个(相对)成熟的、编写良好的包,它有一个很好的API。

无耻的插头:如果你在处理CSRF支票,为什么不试试我的浪花包呢?

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19784687

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档