{"metadata":{"image":[],"title":"","description":""},"api":{"url":"","auth":"never","params":[],"results":{"codes":[]},"settings":""},"next":{"description":"","pages":[]},"title":"Sessions","type":"basic","slug":"sessions","excerpt":"","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 encrypt and sign each cookie to make sure it can't be read or 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/2`, `get_session/2`, and then render only the text that made the session round-trip.\n\n```elixir\ndefmodule HelloPhoenix.PageController do\n  use Phoenix.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```","updates":["55472e736184460d006fd841"],"order":5,"isReference":false,"hidden":false,"sync_unique":"","link_url":"","link_external":false,"_id":"559218ad1da5250d001e9679","project":"54348ec95b10711400c6c445","createdAt":"2014-12-03T22:15:23.725Z","version":{"version":"0.14.0","version_clean":"0.14.0","codename":"","is_stable":false,"is_beta":true,"is_hidden":false,"is_deprecated":false,"categories":["559218ad1da5250d001e9670","559218ad1da5250d001e9671","559218ad1da5250d001e9672","559218ad1da5250d001e9673","559218ad1da5250d001e9674"],"_id":"559218ac1da5250d001e966f","releaseDate":"2015-06-30T04:18:52.132Z","__v":1,"createdAt":"2015-06-30T04:18:52.132Z","forked_from":"5558c642eb56ae2f00f714fc","project":"54348ec95b10711400c6c445"},"__v":0,"githubsync":"","user":"5435e00ad7d8700800bbec51","category":{"sync":{"isSync":false,"url":""},"pages":["559218ad1da5250d001e9675","559218ad1da5250d001e9676","559218ad1da5250d001e9677","559218ad1da5250d001e9678","559218ad1da5250d001e9679","559218ad1da5250d001e967a","559218ad1da5250d001e967b","559218ad1da5250d001e967c","559218ad1da5250d001e967d","55921ed65068e60d002ba044"],"title":"Bonus Guides","slug":"bonus-guides","order":4,"from_sync":false,"reference":false,"_id":"559218ad1da5250d001e9672","version":"559218ac1da5250d001e966f","__v":2,"createdAt":"2014-12-03T21:36:49.014Z","project":"54348ec95b10711400c6c445"}}
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 encrypt and sign each cookie to make sure it can't be read or 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/2`, `get_session/2`, and then render only the text that made the session round-trip. ```elixir defmodule HelloPhoenix.PageController do use Phoenix.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 ```