DEV Community

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

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.