Sessions
Phoenix gets its session functionality from Plug. Plug ships with two forms of session storage out of the box - cookies, and Erlang Term Storage (ETS).
Cookies
Phoenix uses Plug’s cookie session storage by default. The two things that make this work are having a secret_key_base
configured for our environment - this includes the base config/config.exs
- and the correct configuration for Plug.Session
in our endpoint.
Here’s the config/config.exs
file from a newly generated Phoenix application, showing the secret_key_base
set for us.
config :hello, HelloWeb.Endpoint,
url: [host: "localhost"],
root: Path.dirname(__DIR__),
secret_key_base: "some_crazy_long_string_phoenix_generated",
debug_errors: false,
pubsub: [name: Hello.PubSub,
adapter: Phoenix.PubSub.PG2]
Plug uses our secret_key_base
value to sign each cookie to make sure it can’t be tampered with.
And here is the default Plug.Session
configuration from lib/hello_lib/hello_web/endpoint.ex
.
defmodule HelloWeb.Endpoint do
use Phoenix.Endpoint, otp_app: :hello
. . .
plug Plug.Session,
store: :cookie,
key: "_hello_key",
signing_salt: "Jk7pxAMf"
. . .
end
ETS
Phoenix also supports server-side sessions via ETS. To configure ETS sessions, we need to create an ETS table when we start our application. We’ll call ours session
. We also need to re-configure Plug.Session
in our endpoint.
Here’s how we would create an ETS table on application startup in lib/hello.ex
.
def start(_type, _args) do
import Supervisor.Spec, warn: false
:ets.new(:session, [:named_table, :public, read_concurrency: true])
. . .
In order to re-configure Plug.Session
, we need to change the store, specify the name of the key for the ETS table, and specify the name of the table in which we are storing the sessions. The secret_key_base
is not necessary if we are using ETS session storage.
Here is how it looks in lib/hello/endpoint.ex
.
defmodule HelloWeb.Endpoint do
use Phoenix.Endpoint, otp_app: :hello
. . .
plug Plug.Session,
store: :ets,
key: "sid",
table: :session,
. . .
end
While we can use ETS for session storage, it might not be the best idea. This is from the Plug.Session
documentation.
We don’t recommend using this store in production as every session will be stored in ETS and never cleaned until you create a task responsible for cleaning up old entries.
Also, since the store is in-memory, it means sessions are not shared between servers. If you deploy to more than one machine, using this store is again not recommended.
Accessing Session Data
With the proper configuration in place, we can access session data in our application’s controllers.
Here’s a really quick example of putting a value into the session and getting it out again. We can change the index
action of our generated HelloWeb.PageController
at lib/hello_web/controllers/page_controller.ex
to use put_session/3
, get_session/2
, and then render only the text that made the session round-trip.
defmodule HelloWeb.PageController do
use HelloWeb, :controller
def index(conn, _params) do
conn = put_session(conn, :message, "new stuff we just set in the session")
message = get_session(conn, :message)
text conn, message
end
end