当前位置: 首页 > 面试题库 >

编写按处理器的中间件

糜宜民
2023-03-14
问题内容

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

我已经阅读了一些有关此的文章,但是许多示例着重于每个服务器的中间件(包装http.Handler):我有一小部分需要中间件的处理程序。我的其他大部分页面都没有,因此,如果可以避免检查会话等。对于那些要求更好。

到目前为止,我的中间件通常看起来像这样:

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,否则它将重定向他们(因为他们没有预览内容!)。

我想将该结构传递给包装的处理程序,以节省重复会话的需要。我刚刚在中间件中编写的获取/类型声明/错误检查逻辑。

我可以这样写:

type CSRFHandlerFunc func(w http.ResponseWriter, r *http.Request, t string)

…然后像这样编写中间件:

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应用程序方面一直 很棒 ,但是在它的现阶段尚无大量示例,因此我有点儿依赖。


问题答案:

如果我正确理解了您的问题,那么您正在寻找一种将其他参数传递给中间件的便捷方法,对吗?

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

但是在您的情况下,您似乎想要传递每个请求参数,例如CSRF令牌。将这些参数传递给处理函数将修改其签名,并且会偏离标准Handler[Func]接口。在这种情况下,中间件之间的紧密耦合是正确的。

您曾提到过自己的解决方案– 我认为上下文地图 解决此问题的可行工具。这不是 很难一个写自己-
你基本上需要map[*http.Request]interface{}RWMutex安全的并发访问。尽管如此,仅仅使用gorilla/context就足够了–看起来(相对)成熟,编写良好的包,带有不错的API。

无耻的插件:如果您要处理CSRF检查,为什么不试试我的nosurf软件包呢?



 类似资料:
  • 我想做一个新的处理器,它将是GetFile和EvaluateXpath的重聚。有几个主题我感兴趣: > 现在我的nar文件超过20KB,而我的nifi无法运行它,我该如何缩小它? 我想从文件夹中获取文件,读取它的数据并将其作为一个atribute放入新的flowfile中,然后将配置xml回滚到它的原始文件夹,如何将配置文件回滚到文件夹b代码? 下面是我用来从xml配置文件中获取属性的简单代码:

  • 在我的Spring boot和Spring batch应用程序中,我有这样一个步骤: 我的作家是一个空的,如下所示: 现在,在我的处理器中,我有: 问题:由于所有对象都传递给处理器,我可以在处理器本身中处理它们,而不是使用任何转换等,因为我的目的通过使用处理器来解决,这是一个好的做法吗?或者我必须使用作家/自定义作家来完成工作?

  • 我目前正在编写一个Spring批处理,其中我正在读取一个数据块,并对其进行处理,然后我希望将此数据传递给两个Writer。一个writer将简单地更新数据库,而第二个writer将写入csv文件。 我计划编写自己的自定义编写器,并在customItemWriter中注入这两个ItemWriter,并在customItemWriter的write方法中调用这两个ItemWrite的write方法。这

  • 关于skip,我有一个非常基本的问题。我正在使用spring示例提供的spring batch simple cli项目,并试图理解跳过行为。它有一个非常基本的示例读取器,可以读取字符串数组(我将其修改为从Hellowworld 1到Hellowworld 10的10个字符串列表中读取),还有一个基本的编写器,可以登录到控制台。writer抛出java。每写一次都有例外。我在作业配置中增加了4个跳

  • 问题内容: 我可能只是看错了方向,但我发现有关批注处理的JSE文档非常稀疏。我想编写一个注释处理器,该处理器处理带注释的String字段和局部变量,以计算的String表达式替换它们。这应该不会太复杂,但是我对于Javax.annotation.processing的Javadoc却迷失了。 编辑:我需要在编译时处理批注,因为我想修改生成的代码。它应将带注释的常量String表达式替换为计算的St

  • 本文向大家介绍在Django框架中编写Context处理器的方法,包括了在Django框架中编写Context处理器的方法的使用技巧和注意事项,需要的朋友参考一下 写Context处理器的一些建议 编写处理器的一些建议:     使每个context处理器完成尽可能小的功能。 使用多个处理器是很容易的,所以你可以根据逻辑块来分解功能以便将来复用。     要注意 TEMPLATE_CONTEXT_