HMAC, Elixir, Plug.Conn (пытается вызвать read_body более одного раза)
Я борюсь с проблемой, когда что-то читает тело http-запроса, прежде чем Plug.Parsers.JSON получает его в конвейере. Из-за этого время ожидания read_body в плагине json - вы не можете прочитать тело дважды.
У нас есть реализация HMAC в более ранней версии нашего конвейера, и в некоторых случаях она читает тело. Есть ли образец поведения тела в Plug? Я имею в виду, если мы можем прочитать его только один раз, и он должен быть декодирован в Plug.Parsers.JSON, ну... это не сработает.
Следуй по вопросу. Нужно ли включать тело запроса при создании хэша HMAC? Я имею в виду, мне кажется, что мы должны это сделать, но я думал, что в этот момент я оказался в кругу.
Спасибо!
1 ответ
Вы можете передать обычай :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.