HMAC,Elixir,Plug.Conn(尝试多次调用read_body)

时间:2018-07-27 16:57:06

标签: elixir phoenix-framework hmac plug

我正在努力解决一个问题,即在Plug.Parsers.JSON将其放入管道之前,有人正在读取http请求的正文。因此,json插件中的read_body超时-您不能两次读取正文。

我们在管道的较早版本的插件中有一个HMAC实现,在某些情况下它会读取主体。在Plug中,有没有使用主体的行为方式?我的意思是,如果我们只能读取一次,并且必须在Plug.Parsers.JSON中进行解码,那么……它将无法正常工作。

关注。生成HMAC哈希时,是否需要包括请求主体?我的意思是,我觉得我们必须这样做,但目前我以为自己是一个圈子。

谢谢!

1 个答案:

答案 0 :(得分:2)

您可以将自定义:body_reader选项传递给Plug.Parsers,以缓存正文以供以后使用。

您将不希望在解析器之前读取主体,而是缓存主体以稍后从要对其进行哈希处理的插件中读取。

Option

  

:body_reader-的可选替换项(或包装)   Plug.Conn.read_body/2提供的功能可以访问   原始主体在解析和丢弃之前。在标准中   {Module, :function, [args]}(MFA)的格式,默认为   {Plug.Conn, :read_body, []}

Example

  

有时您可能需要自定义解析器从中读取正文的方式   连接。例如,您可能想要缓存主体以执行   稍后进行验证,例如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中。