session - 如何在 Plug 中设置 session 和 CSRF 保护?

标签 session csrf session-management elixir

我目前正在通过尝试制作一个小型 Plug 项目来学习 Elixir。除了 session 和 CSRF 保护之外,大部分都很好。当我发出 GET 请求时,我在 Firefox 或 HTTPie 中看不到 session cookie,当我发出 POST 请求时,我收到 500 错误(但记录器没有提示)。

这是我当前的路由器代码:

defmodule ElxSimpleApi.Web do
  require Logger

  use Plug.Router
  import Plug.Conn

  alias ElxSimpleApi.{Models, Repo}

  plug Plug.Logger, log: :debug
  plug Plug.Parsers, parsers: [:urlencoded, :json],
    pass: ["text/*", "application/json"],
    json_decoder: Poison

  plug :put_secret_key_base

  plug Plug.Session, store: :cookie,
    key: "_elx_simple_api_session",
    encryption_salt: "elxsimpleapienc",
    signing_salt: "elxsimpleapisign",
    log: :debug
  plug :fetch_session
  plug Plug.CSRFProtection


  plug :match
  plug :dispatch

  # A bunch of routes here, omitted for clarity

  match _ do
    send_resp(conn, 404, "oops")
  end

  defp fetch_person(:int, id), do: Models.Person |> Repo.get(id)
  defp fetch_person(:str, sid), do: fetch_person(:int, String.to_integer(sid))

  defp ecto_to_map(struct) do
    struct |> Map.from_struct |> Map.drop([:__meta__])
  end

  defp put_secret_key_base(conn, _) do
    put_in conn.secret_key_base, "d5b2hHZGsUfcYB8lImcxooaLfVBlB5bg/z9a99jjHuXTvt7yb5neykHrYEjuNFnD"
  end
end

请告诉我我做错了什么。谢谢!

更新:感谢@josé-valim 的建议,我现在知道 500 错误是由于无效的 CSRF token 造成的。但 cookie 仍未设置。

最佳答案

显然,问题与 this issue: 有关Plug.CSRFProtection 不会自动将 CSRF token 放入 session 中,并且 Plug.Session 在放入某些内容之前不会真正创建 session 。

我必须添加这个插件(在 plug Plug.CSRFProtection 之后):

defp put_csrf_token_in_session(conn, _) do
  Plug.CSRFProtection.get_csrf_token
  conn |> put_session("_csrf_token", Process.get(:plug_unmasked_csrf_token))
end

关于session - 如何在 Plug 中设置 session 和 CSRF 保护?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47892222/

相关文章:

php - 如何在 PHP 中取消设置 cookie?

java - 保存大量动态用户输入

java - 使用 Ehcache 的 WebApp session 管理

csrf - 防止CSRF?

java - session 管理遇到问题

php - 在请求之间记住 PHP 中的对象状态

javascript - 带有csrf token 的Angular SpringBoot SpringSecurity应用程序Ajax POST在未定义 token /头时失败

javascript - 具有跨域的angular js应用程序中的CSRF保护

c# - 当 session 过期时, session 管理器不会将我注销,HTTPContext.Current 为 Null

multithreading - Spring + Hibernate 跨多个线程的 session 管理