我正在努力解决一个问题,即在Plug.Parsers.JSON将其放入管道之前,有人正在读取http请求的正文。因此,json插件中的read_body超时-您不能两次读取正文。
我们在管道的较早版本的插件中有一个HMAC实现,在某些情况下它会读取主体。在Plug中,有没有使用主体的行为方式?我的意思是,如果我们只能读取一次,并且必须在Plug.Parsers.JSON中进行解码,那么……它将无法正常工作。
关注。生成HMAC哈希时,是否需要包括请求主体?我的意思是,我觉得我们必须这样做,但目前我以为自己是一个圈子。
谢谢!
答案 0 :(得分:2)
您可以将自定义:body_reader
选项传递给Plug.Parsers
,以缓存正文以供以后使用。
您将不希望在解析器之前读取主体,而是缓存主体以稍后从要对其进行哈希处理的插件中读取。
:body_reader
-的可选替换项(或包装)Plug.Conn.read_body/2
提供的功能可以访问 原始主体在解析和丢弃之前。在标准中{Module, :function, [args]}
(MFA)的格式,默认为{Plug.Conn, :read_body, []}
。
有时您可能需要自定义解析器从中读取正文的方式 连接。例如,您可能想要缓存主体以执行 稍后进行验证,例如HTTP签名验证。这可以是 通过自定义的身体读取器实现,该读取器可以读取身体并存储 它在连接中,例如:
defmodule CacheBodyReader do def read_body(conn, opts) do {:ok, body, conn} = Plug.Conn.read_body(conn, opts) conn = update_in(conn.assigns[:raw_body], &[body | (&1 || [])]) {:ok, body, conn} end end
然后可以将其设置为:
plug Plug.Parsers, parsers: [:urlencoded, :json], pass: ["text/*"], body_reader: {CacheBodyReader, :read_body, []}, json_decoder: Jason
它已添加到Plug v1.5.1中。