kowainik / cake-slayer

🍰🔪 Architecture of Haskell backend applications
https://kowainik.github.io/projects/cake-slayer
Mozilla Public License 2.0
132 stars 6 forks source link

Replace JWT session management with Cookies #50

Open jonathanjouty opened 5 years ago

jonathanjouty commented 5 years ago

Let me start by saying that this project is really cool and inspirational! Thanks for working on it and putting it out there.

On a recent project I started out by using JWTs as API tokens, but after some research discovered that it really is not a good idea.

They have their use-case, but not as API tokens or client sessions. See Thomas Ptacek's comment on JWTs, and this long discussion.

The tl;dr is:

  1. Use simple bearer tokens for simple API access (use OAuth 2.0 for fancier stuff).
  2. Use cookies with CSRF protection for client sessions. They are battle tested and the security implications have been very well explored.
  3. Don't use JWTs yourself because they are cool, seem easy, and give you the illusion of not needing server-side state.
chshersh commented 5 years ago

@jonathanjouty Thanks for your kind words about the project! Could you please, clarify more on the issues with using JWT? I've read various posts on JWT and GitHub discussion, but I didn't notice any problems with JWT in our case, and I also didn't found any viable alternatives. Also, all explanations on why JWT are bad are quite vague. For example, what can be wrong if we store user_id in JWT and then backend decodes this JWT token to verify whether the user is logged in or not?

jonathanjouty commented 4 years ago

Hey, sorry for taking so long to get back to this. I'll address each of your points.


[...] I didn't notice any problems with JWT in our case [...]

From what I understand, in cake-slayer JWTs are the suggested method to handle user sessions (i.e. someone using a web browser to access the application).

That is a problem in itself!

I've now (re) found the articles that explain this really well:

  1. The full explanation: http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/
  2. The tl;dr (slightly sarcastic) flowchart: http://cryto.net/~joepie91/blog/2016/06/19/stop-using-jwt-for-sessions-part-2-why-your-solution-doesnt-work/

[...] I also didn't found any viable alternatives.

From [1] above:

Stateful JWT tokens are functionally the same as session cookies, but without the battle-tested and well-reviewed implementations or client support.

Unless you work on a Reddit-scale application, there's no reason to be using JWT tokens as a session mechanism. Just use sessions.

Here "sessions" means server-side stateful sessions, almost always implemented using cookies (following OWASP best practices). Facebook, Google, Reddit, GitHub... everyone uses them!


[...] all explanations on why JWT are bad are quite vague. For example, what can be wrong if we store user_id in JWT and then backend decodes this JWT token to verify whether the user is logged in or not?

The post [1] above goes into specifics very nicely, I should have linked to that originally.


Hopefully this provides sufficient information.

jonathanjouty commented 4 years ago

@chshersh did my explanation help or further confuse things? I can try again if need be :)

chshersh commented 4 years ago

@jonathanjouty Thanks for your reply and time to write the answer! I appreciate that 👍 Sorry, we didn't have time to look into this JWT issue, since we've been busy with other stuff. But I have this issue in my bookmarks on GitHub and I have plans to return back to it and study the problem carefully 🙂

chshersh commented 4 years ago

This issue was in my bookmarks for a long time... I've researched the User Authentication and Session Management topics thoroughly, and cookies indeed seem like a better option. We will update the architecture once we have enough time for it 🙂