{"_id":"5777c96e5b2b430e00b982c5","__v":0,"parentDoc":null,"project":"54348ec95b10711400c6c445","user":"5435e00ad7d8700800bbec51","category":{"_id":"5777c9635b2b430e00b982aa","version":"5777c9635b2b430e00b982a5","project":"54348ec95b10711400c6c445","__v":0,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2014-12-03T21:36:49.014Z","from_sync":false,"order":4,"slug":"bonus-guides","title":"Bonus Guides"},"version":{"_id":"5777c9635b2b430e00b982a5","__v":1,"project":"54348ec95b10711400c6c445","createdAt":"2016-07-02T14:02:11.084Z","releaseDate":"2016-07-02T14:02:11.084Z","categories":["5777c9635b2b430e00b982a6","5777c9635b2b430e00b982a7","5777c9635b2b430e00b982a8","5777c9635b2b430e00b982a9","5777c9635b2b430e00b982aa"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"1.2.0","version":"1.2.0"},"updates":["55472e736184460d006fd841","568a7e94bf86800d00fe3111"],"next":{"pages":[],"description":""},"createdAt":"2014-12-03T22:15:23.725Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"never","params":[],"url":""},"isReference":false,"order":7,"body":"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).\n\n## Cookies\n\nPhoenix 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.\n\nHere's the `config/config.exs` file from a newly generated Phoenix application, showing the `secret_key_base` set for us.\n\n```elixir\nconfig :hello_phoenix, HelloPhoenix.Endpoint,\n  url: [host: \"localhost\"],\n  root: Path.dirname(__DIR__),\n  secret_key_base: \"some_crazy_long_string_phoenix_generated\",\n  debug_errors: false,\n  pubsub: [name: HelloPhoenix.PubSub,\n           adapter: Phoenix.PubSub.PG2]\n```\n\nPlug uses our `secret_key_base` value to sign each cookie to make sure it can't be tampered with.\n\nAnd here is the default `Plug.Session` configuration from `lib/hello_phoenix/endpoint.ex`.\n\n```elixir\ndefmodule HelloPhoenix.Endpoint do\n  use Phoenix.Endpoint, otp_app: :hello_phoenix\n. . .\n  plug Plug.Session,\n    store: :cookie,\n    key: \"_hello_phoenix_key\",\n    signing_salt: \"Jk7pxAMf\"\n. . .\nend\n```\n\n## ETS\nPhoenix 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.\n\nHere's how we would create an ETS table on application startup in `lib/hello_phoenix.ex`.\n\n```elixir\ndef start(_type, _args) do\n  import Supervisor.Spec, warn: false\n  :ets.new(:session, [:named_table, :public, read_concurrency: true])\n. . .\n```\n\nIn 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.\n\nHere is how it looks in `lib/hello_phoenix/endpoint.ex`.\n\n```elixir\ndefmodule HelloPhoenix.Endpoint do\n  use Phoenix.Endpoint, otp_app: :hello_phoenix\n  . . .\n  plug Plug.Session,\n    store: :ets,\n    key: \"sid\",\n    table: :session,\n  . . .\nend\n```\n\nWhile we can use ETS for session storage, it might not be the best idea. This is from the `Plug.Session` documentation.\n\n> 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.\n\n> 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.\n\n## Accessing Session Data\n\nWith the proper configuration in place, we can access session data in our application's controllers.\n\nHere'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 `HelloPhoenix.PageController` at `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.\n\n```elixir\ndefmodule HelloPhoenix.PageController do\n  use HelloPhoenix.Web, :controller\n\n  def index(conn, _params) do\n    conn = put_session(conn, :message, \"new stuff we just set in the session\")\n    message = get_session(conn, :message)\n\n    text conn, message\n  end\nend\n```","excerpt":"","slug":"sessions","type":"basic","title":"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. ```elixir config :hello_phoenix, HelloPhoenix.Endpoint, url: [host: "localhost"], root: Path.dirname(__DIR__), secret_key_base: "some_crazy_long_string_phoenix_generated", debug_errors: false, pubsub: [name: HelloPhoenix.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_phoenix/endpoint.ex`. ```elixir defmodule HelloPhoenix.Endpoint do use Phoenix.Endpoint, otp_app: :hello_phoenix . . . plug Plug.Session, store: :cookie, key: "_hello_phoenix_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_phoenix.ex`. ```elixir 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_phoenix/endpoint.ex`. ```elixir defmodule HelloPhoenix.Endpoint do use Phoenix.Endpoint, otp_app: :hello_phoenix . . . 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 `HelloPhoenix.PageController` at `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. ```elixir defmodule HelloPhoenix.PageController do use HelloPhoenix.Web, :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 ```