HMAC、Elixir、Plug.Conn(试图多次调用 read_body)

HMAC, Elixir, Plug.Conn (trying to call read_body more than once)

我正在努力解决一个问题,即某些东西在 Plug.Parsers.JSON 进入管道之前正在读取 http 请求的 body。因此,json 插件中的 read_body 超时——您无法读取 body 两次。

我们在管道的早期插件中有一个 HMAC 实现,它在某些情况下读取 body。 body 的使用在 Plug 中的行为是否有模式?我的意思是,如果我们只能读取一次,并且必须在 Plug.Parsers.JSON 中对其进行解码,那么......它不会起作用。

关注问题。生成 HMAC 哈希时是否需要包含请求 body?我的意思是,我觉得我们必须这样做,但此时我认为自己陷入了困境。

谢谢!

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

您不希望在解析器之前读取正文,而是缓存正文以便稍后从想要散列它的插件中读取。

Option:

:body_reader - an optional replacement (or wrapper) for Plug.Conn.read_body/2 to provide a function that gives access to the raw body before it is parsed and discarded. It is in the standard format of {Module, :function, [args]} (MFA) and defaults to {Plug.Conn, :read_body, []}.

Example:

Sometimes you may want to customize how a parser reads the body from the connection. For example, you may want to cache the body to perform verification later, such as HTTP Signature Verification. This can be achieved with a custom body reader that would read the body and store it in the connection, such as:

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

which could then be set as:

plug Plug.Parsers,
  parsers: [:urlencoded, :json],
  pass: ["text/*"],
  body_reader: {CacheBodyReader, :read_body, []},
  json_decoder: Jason

添加于Plug v1.5.1