DEV Community

Discussion on: What is really the difference between Cookie, Session and Tokens that nobody is talking about ?.

incrementis profile image
Akin C.

Hello nshimiye_emmy,

thank you for your article.
It helped me understand Token a bit better.
This part helped me the most:

"[...]if you click yes the app will receive a token granting access to your transactions but the app will only view transactions, it will not be able to wire transfers or to see other details which you would normally be able to see when you login in your bank account. "

Still, I understand that in a bad situation the app will tell you, it will only read transactions, but the truth is, it could request a token that offers more than just reading options without you knowing, right? Wouldn't it be wiser to tell the bank what token the app can use? I apologize in advance if I get anything wrong here :)!

dev_emmy profile image
nshimiye_emmy Author

The bank is the one responsible for giving the token to another app, so it really knows what king of access granting it should give to a third-party website or app.

codingsafari profile image
Nico Braun • Edited on

You could achieve this with cookie or session-cookie as well.

Cookies are key value pairs which exists in the header and are typically added by the server to the response. You could have a cookie username and another one userrole for example. Using cookies like this is the least secure option as all the information is available in the cookies.

Sessions are cookies but instead of putting "real information" in the cookie, only an ID is sent, the so called "session-id". This way the client doesn't actually know what is in the session, only the server can look it up, when receiving the request.
When using a session, the backend is required to know which sessions exist. The backend is "stateful". So if you would run your backend a second time and send the session-cookie generated by the first backend to the second backend, the second backend would mark the session as invalid and prompt the user to login.
Like normal cookies, it can be tricky to use them effectively cross domain (from a browser).

Tokens move the state away from the backend and again onto the client. Much like regular "non session" cookies do. But they are encrypted which makes it harder to tamper with.
Since each client carries their own state, the backend can be "stateless" so that the token from one backend works with any other backend. The service is "horizontally scalable".
Since tokens don't have to be sent in the cookie header, it becomes also more easy to work cross domain and/or between services.
When using tokens from a browser, it can be tricky to find a safe place to store them, a lot of times people will put the JWT actually in a http-only cookie header.

kevinmduffey profile image
Kevin Duffey

I'd like to add to.. or perhaps amend Nico's statement a bit about Tokens... while technically correct.. tokens keep the state (as much as the server implementation puts in it).. the client should ideally NOT have access to decode/use the token itself. The server should only send the token on specific path (like /login /token, /refresh, etc) and should be httpOnly and secure.. so that the JS code in a client can not access or decode the token. You might ask.. then how the heck is the client app supposed to get at the details to say.. display the name, email, etc? Well.. when the request to login is made.. which returns the generated token at that point.. it would also return a response body with JSON (for example) that contains the bits the client would use in say the UI. Some might say.. well this is insecure.. but think about it (if you are one of those that think this is the case).. accessing and decoding the token in the client is even less secure and the result is the same (and even more) data. So.. the way a server should use JWT tokens.. is to store things like useId (or the user of that session), and other pieces of data that allow the server side (upon receiving future requests WITH the token) to decode the token, pull the values out and use them in some manner than negates the need to do a DB lookup on every request. Say.. to do a DB query that needs the userId (which is likely a column in several tables in order to tie things to that user). This ultimately keeps the server side largely stateless.. and avoids the client side from accessing secure things like userId.. which should never be allowed to be accessed by consumer UNLESS the system is built that way.. which is as far as I have understood..bad design. If anything, make use of UUIDs as secondary IDs that can be changed/migrated/etc without affecting the actual DB structure.
Their are of course many ways this can be modified to do more or less the same thing.. but just wanted to put it out their that ideally the JWT token should NOT be decoded by the client.. and should NOT be stored in local storage. It should be httpOnly flag, secure flag and only as a cookie.. so for browsers and many nodejs/js libraries.. automatically sent on every request (or those that match the path the token is issued for).

Thread Thread
codingsafari profile image
Nico Braun • Edited on

I said that tokens are encrypted which implies that the client cant "decode" it . Which actually should read "decrypt".
Base64 for example, is encoding. Sha256 which is usually used for json web tokens is encryption.

Also tokens are oftemtimes not sent in a httpOnly cookie header, as this is is for cookies only and is sometimes tricky to use. Many times you will find the token actually in the auth header with the Bearer prefix. Sometimes called bearer token. In fact Oauth2 is using bearer tokens.

Again the client cant decrypt the token so thats not a problem. The issue with storing the token in localStorage for example is not that someone could read the claims, but that someone could take the whole token without really knowing whats inside and still authenticate.

And saying all of this, you have to keep in mind that those tokens were also partwise designed to make the work between services easier. So all those browser concepts dont always apply. Like localStorage or httpOnly cookies.
When using token form your own backend you can just store it in memory for example.

Thread Thread
codingsafari profile image
Nico Braun

I was wrong on one ascpect here. The header and the payload are indeed only encoded. Only the signature is encrypted. So anyone can read the payload.