Raxx.Session
Manage HTTP cookies and storage for persistent client sessions.
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.