Botonomous
Botonomous

Reputation: 1764

Phoenix Session Identifier

I am creating an application that will authenticate users and forward them to a redirect URL that was passed into the first get request.

Flow is as so: 1. User clicks on a static URL not hosted within application. 2. Authenticate request (GET) (params = redirect URL)
3. (user submits a form) -> (Authenticate) (POST) (params = redirect URL & user & pass) 4. Auth occurs on server and either forwards them to the redirect, or dumps to an invalid login page.

My question is so: I don't want to display the login page if the user has successfully authenticated in an N timespan. I can handle that logic with a genserver no problem. But is there a way to create a unique session storage before I hit the POST which will hang on to the user before I display the form?

In ASP.NET the session container is already unique between users, so I am looking to see if there is something similar with phoenix.

Thanks for your help.

Upvotes: 3

Views: 1621

Answers (1)

Stelios Joseph Karras
Stelios Joseph Karras

Reputation: 483

You can create a random id and save it into the session using a plug.

defmodule App.Plugs.SessionId do

  @behaviour Plug

  import Plug.Conn

  @impl true
  def init(default), do: default

  @impl true
  def call(conn, _config) do
    case get_session(conn, :session_id) do
      nil ->
        session_id = unique_session_id()
        put_session(conn, :session_id, session_id)

      session_id ->
        conn
    end
  end

  defp unique_session_id() do
    :crypto.strong_rand_bytes(16) |> Base.encode16()
  end
end

But be aware that :crypto.strong_rand_bytes return an error if the entropy of the system is low.

and in your pipeline in the file router.ex you will need to add it after the fetch_session plug like this

...
plug(:fetch_session)
plug(App.Plugs.SessionId)
....

Then you can retrieve the session id in the your controller like

session_id = get_session(conn, :session_id)

Upvotes: 2

Related Questions