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).
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.
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
defmodule HelloWeb.Endpoint do use Phoenix.Endpoint, otp_app: :hello . . . plug Plug.Session, store: :cookie, key: "_hello_key", signing_salt: "Jk7pxAMf" . . . end
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
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
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
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.
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
lib/hello_web/controllers/page_controller.ex to use
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