thojanssens1

thojanssens1

Phx_gen_auth: Session cookies and remember-me cookies

Hello

In the generated authentication code by phx_gen_auth, I learn the following:

A “session cookie” maintains the user logged in for the duration of the browser session (until the browser is completely closed generally). The cookie contains the user session token.

In addition to the session cookie, and in order to keep the user logged in after browser closes/re-opens, I can use a “remember me cookie”, with a long expiration date. With the generated auth code, the user can check a checkbox for the server to maintain his session for e.g. 60 days through the remember me cookie.

Questions:

Renowned apps such as Facebook, StackOverflow, Gmail, (and most modern apps?) … do not provide the user with an option to keep longer session. The session are by default long so that the user stays logged in after browser closes. Correct me if I’m wrong, but this is mostly what we see today.

I was then wondering why didn’t we, by default, follow that approach of maintaining sessions, as it also allows for simpler code : working with one cookie vs two cookies (e.g. the current code is trying to fetch the logged in user from the session cookie, and if not found, try to find in the remember me cookie, and then if found, sets the session cookie, …).

Tokens in cookies are considered safe (as opposed as stored in browser), hence I don’t see the interest to have by default short-lived sessions that expire on closing the browser. Maybe in the case multiple users use the same computer?

However, what most app do though is prolonging the session automatically on logging in. With this mechanism, I didn’t have to enter my passwords in ages… This seems lacking in the generated authentication code, but again because another approach is used : have the remember me cookie expire after a precise amount of days.

So instead of a session cookie + remember me cookie expiring on a precise amount of days, on user’s consent, why not have a single session cookie expire after an amount of days, without user’s consent, and prolong that expiration date on login.

Marked As Solved

josevalim

josevalim

Creator of Elixir

You should look at the general authentication suite those apps provide. I have 2FA enabled and, at least for me, Google asks if I should trust the device for 60 days once I enter the code. This is quite similar to the remember me token.

Google also tracks my IP, user agent, and who knows what else. They e-mail me when they think something is amiss. I wouldn’t even be surprised if they have heuristics for “shared computer like usage”. For example, you can use a cookie to track all the different people who login to Gmail from a computer, and once you get 5 different people, they can assume it is a shared computer and automatically reduce how long the session lasts.

Therefore, I think it would be a mistake to look at Google/Facebook and say “hey, we can do the same”, without taking into account all of the other steps they may have taken to make this feature possible.

In any case, you can most likely change Plug.Session to make your session last longer by default. I will personally continue requiring this choice to be opt-in though.

Also Liked

lucaong

lucaong

Actually, @thojanssens1, while I was referring to generic best practices, looking at the specific implementation of phx_gen_auth it looks you are right on the first point: the remember token is not refreshed and invalidated after use. So I stand corrected.

It might be something missing in phx_gen_auth. As far as I know, best practice would be to delete the user token and issue a new remember me cookie after exchanging the old one for a logged-in session. As the blog post I linked before says, one of the main points of the remember me cookie approach was to be single-use. Many apps even remove all tokens for a user when an attempt to reuse an old one occurs, considering it the sign of a breach.

Re-issuing a new remember me cookie for every usage also has the advantage to remember the user for X days since the most recent session, as opposed to X days since the last explicit login (in other words, logging out the users after X days of inactivity).

If what said about phx_gen_auth is correct, you have a point that the remember cookie and the session cookie are basically equipotent in this implementation.

It would be interesting to know @josevalim take on this, if that was a deliberate choice and why.

josevalim

josevalim

Creator of Elixir

I don’t think this would be desired. It means that if I forget to sign out somewhere, someone can continue logging in forever. We need to require re-authentication at some point.

Session tokens are short lived. Given people have multiple devices today, it can be very common for people to try to login with old tokens. So adopting such a policy can lead to bad UX as we would be constantly logging out users across devices.

josevalim

josevalim

Creator of Elixir

That would be ok. They are both cookies after all. As @lucaong said and you mentioned though, the session does contain other data that you may not want to persist. So having two separate cookies is less “coupling”.

Where Next?

Popular in Questions Top

chokchit
** (DBConnection.ConnectionError) connection not available and request was dropped from queue after 2733ms. You can configure how long re...
New
New
Kurisu
For example for a current url like http://localhost:4000/cosmetic/products?_utf8=✓&query=perfume&page=2, I would like to get: ...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
JulienCorb
I am trying to implement my new.html.eex file to create new posts on my website. new.html.eex: <h1>Create Post</h1> <%= ...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: The documentation above suggests that while ...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

Other popular topics Top

hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a > b) do {:ok, "a"} end if (a < b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement