smpallen99 / coherence

Coherence is a full featured, configurable authentication system for Phoenix
MIT License
1.27k stars 225 forks source link

Question: Understanding credential storage #375

Open Will-W opened 6 years ago

Will-W commented 6 years ago

I have coherence integrated into my Phoenix app, and it is working really well, but I'm a little confused by some of the underlying implementation details about credential storage, and would like to understand how it works. I've had a dig through the docs and code and some things are clearer, but not everything.

[ I hope this is the correct place to ask questions like this, if not please let me know where ]

I'm using the Authentication.Session. My understanding is that this places some information in the Phoenix session storage (a cookie in my case), which then links to some storage in a Server.

Why is separate server-side storage needed? Why can't the relevant information just be put in the Phoenix session, which is signed and therefore should be secure? When I have implemented a simple version of login in the past, I just stored the user id in the session to indicate 'logged in', and then could retrieve the user information from the database using that id on every request. That seemed to solve all of the session and 'remembering' issues with no server state. What are the extra things that Coherence achieves that my naive approach doesn't?

I have further questions about the 'rememberable' functionality, but that may well all become clear if I understand the above.

Thanks in advance for help - Coherence has been great for me.

junjizhi commented 6 years ago

@Will-W From my experience working with Rails, server side storage can enable you to expire a token. Without server side storage, cookie becomes the source of truth, and server has to trust the cookie, even though it's encrypted. You may encode the expiry time in the cookie, but once it's encoded, it can't be revoked. With server side, you can store the token expiry in the database instead of cookie. Expiring a token can just be updating a field in db.

P.S. I'm quite new to coherence too. So my answer to this question may not reflect the exact coherence implementation.

smpallen99 commented 6 years ago

@Will-W Great question! And I'm ok using this form for questions. All I ask is that you close the issue when ur happy with the response :)

The server side state storage is used to load the user schema into the conn.assigns.current_user on each authenticated request. All we store in the client's session is a unique key generated when you login. It is considered bad practice to store large amounts of data in the session object since its passed to the server with each request.

Additionally, Coherence's default implementation stores the user's schema in-memory (a GenServer) to avoid a database fetch on each request. This approach is problematic if the server restarts since the GenServers state is wiped out.

I have an example on the wiki for adding a database backed store for the session data. When done this way, the in-memory if first checked, and if not found, the database is checked. If found in the database, the in-memory store is updated to optimize subsequent requests.

For the rememberable implementation, it is design to detect stolen session data. When enabled a rememberable hash is added to the user's session. On each request, the hash is compared to the database and a new hash is created and put in the session.