Raxx.Session

Manage HTTP cookies and storage for persistent client sessions.

Hex pm License

Extract, Embed, Expire a session

defmodule MyApp.Action do
  use Raxx.SimpleServer
  alias Raxx.Session

  def handle_request(request, state) do
    {:ok, session} = Session.extract(request, state.session_config)
    updated_session = # ... processing

    response(:ok)
    |> Session.embed(updated_session, state.session_config)

    # ... something went wrong
    response(:forbidden)
    |> Session.expire(state.session_config)
  end
end

Sessions are extract and embedded in their entirety from requests/responses. A session is just a map where any term can be saved, although large terms might not work with certain session stores.

If a session is updated it MUST be embedded in the response, otherwise the client will send the same previous session.

Flash

Flash protection used the :_flash key in a session, it should not be manipulated directly

A flash is information that should be shown to a user only once. Raxx.Session provides some simple helpers to working with flashes.

defmodule MyApp.Action do
  use Raxx.SimpleServer
  alias Raxx.Session

  def handle_request(%{path: ["set-flash"]}, state) do
    session = %{}
      |> Session.put_flash(:info, "Welcome to flash!")
      |> Session.put_flash(:error, "Welcome to flash!")
    redirect("/show-flash")
    |> Session.embed(session, state.session_config)
  end

  def handle_request(request = %{path: ["show-flash"]}, state) do
    {:ok, session} = Session.extract(request, state.session_config)

    {flashes, session} = Session.pop_flash(session)

    response(:ok)
    |> render(flashes)
    |> Session.embed(session, state.session_config)
  end
end

CSRF Protection

CSRF protection used the :_csrf_token key in a session, it should not be manipulated directly

Raxx.Session.extract/2 is protected against CSRF attacks. Sessions can be extracted from safe requests. These are GET, HEAD or OPTIONS requests and they should have no side effect.

Requests with other methods must provide a csrf_token. By default this value is looked for in the x-csrf-token header.

If the token is sent to the server in a different manner it can be explicitly passed by using Raxx.Session.extract/3. For example if it is passed in the body of a request

{%{"_csrf_token" => token}} = URI.decode(request.body)

{:ok, session} = Raxx.Session.fetch(request, token, config)

A CSRF token should not be sent back to the server as a query parameter.

Configuration

session_config = Raxx.Session.config(
                    key: "my_session",
                    store: Raxx.Session.SignedCookie,
                    secret_key_base: String.duplicate("squirrel", 8),
                    salt: "epsom"
                  )

For all configuration options see Raxx.Session or specific stores.

Plug sessions

Sessions from Plug applications can be verified in Raxx applications, and visa versa, if setup with the same configuration.