Pet*_*ton 5 elixir phoenix-framework plug
我需要检查发送到phoenix服务器的JSON内容的摘要。要检查消化,需要生肉。有什么方法可以比解析器更晚地在管道中访问插件中的原始内容。我想将以下摘要验证插件添加到管道的末尾,但无法确定它如何访问已发送的原始内容。
plug Plug.Parsers,
parsers: [:urlencoded, :json],
pass: ["*/*"],
json_decoder: Poison
plug Plug.MethodOverride
plug Plug.Head
plug Plug.VerifyDigest
Run Code Online (Sandbox Code Playgroud)
您可以将自定义:body_reader选项传递给以Plug.Parsers缓存正文以供以后使用。
您不希望在解析器之前读取正文,而是缓存正文以便稍后从想要对其进行散列的插件中读取。
:body_reader- 一个可选的替换(或包装器),Plug.Conn.read_body/2用于提供一个函数,该函数可以在解析和丢弃原始主体之前访问它。它采用{Module, :function, [args]}(MFA)的标准格式,默认为{Plug.Conn, :read_body, []}.
有时您可能想要自定义解析器从连接中读取正文的方式。例如,您可能希望缓存正文以稍后执行验证,例如 HTTP 签名验证。这可以通过自定义正文阅读器来实现,该阅读器可以读取正文并将其存储在连接中,例如:
Run Code Online (Sandbox Code Playgroud)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然后可以设置为:
Run Code Online (Sandbox Code Playgroud)plug Plug.Parsers, parsers: [:urlencoded, :json], pass: ["text/*"], body_reader: {CacheBodyReader, :read_body, []}, json_decoder: Jason
它是在Plug v1.5.1中添加的。
我面临着类似的问题,我按照这个思路编写了一个插件(注意我仍在学习,所以这可能会做得更好):
defmodule Esch.Plugs.HMACValidator do
import Plug.Conn
def init(default), do: default
def call(%Plug.Conn{req_headers: req_headers} = conn, _default) do
hmac_code_tuple = List.keyfind(req_headers, "hmac_token", 0)
if hmac_code_tuple do
hmac_code = elem(hmac_code_tuple,1) |> String.downcase
{:ok, body, conn} = read_body(conn)
hmac_test_code = :crypto.hmac(:sha512, "secret", body) |> Base.encode16 |> String.downcase
if hmac_test_code == hmac_code do
params = Poison.decode!(body)
conn
|> assign(:authorized_api_call, true)
|> struct(%{:body_params => params})
else
conn |> put_resp_content_type("text/plain") |> send_resp(401, "Not Authorized") |> halt
end
else
conn
end
end
def call(conn, _default) do
conn
end
end
Run Code Online (Sandbox Code Playgroud)
上述请求将 HMAC 签名正文与请求标头中的 HMAC 签名进行比较。
read_body当签名与预期签名匹配时,我通过在同一代码中解析 JSON 来规避该问题。conn如果请求不适合典型的 API 调用(在我的例子中没有 HMAC-header-token),则该 ection 会被传递,因此不会读取 body_params 。
endpoint.ex然后,我在插入 Plug.Parsers 之前插入上述插件。
...
plug MyApp.Plugs.HMACValidator
plug Plug.Parsers,
parsers: [:urlencoded, :multipart, :json],
pass: ["*/*"],
json_decoder: Poison
...
Run Code Online (Sandbox Code Playgroud)
我从凤凰号的讨论中得到了一些启发:Way to Read Request Body As String
| 归档时间: |
|
| 查看次数: |
1407 次 |
| 最近记录: |