DEV Community

loading...
Cover image for What is really the difference between Cookie, Session and Tokens that nobody is talking about ?.

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

dev_emmy profile image nshimiye_emmy Updated on ・5 min read

To understand the difference between cookies, sessions and tokens we need to get back on the basics. Let's say you want to login to your bank account and you are provided with login screen where you can input your username and password and when you hit the submit button your username and password goes to the bank server.

Then the server need to verify that you are really who you claim to be, so the bank will check against the database to see if your credentials match and if everything looks good the server will return your account overview page but will also create a session in the database with your login event and gives back to you the session_id inform of a cookie, in other words you have exchanged your username and password for this cookie containing the seesion_id, You send your username and password and then you recieve a cookie with a session_id. So the server will store the session information in the database while you will only have the session_id in the cookie which is stored in the file system of your computer, the session_id is randomly generated so it would be hard to guess, and when you logout, the session will be deleted on the server side but also the server will instruct your browser to delete the cookie containing the session_id as well.

Next time when you login and you tend to request a page, your browser will automatically send a cookie containing a session_id which the server will check to see if it is still valid.It is essential to know that the next time your username and password are nolonger required in order to identify you.

Think of a cookie like your Gym_membership_card, it stores your membershipID, additional with other details and when you scan it at the entry, it checks if your membership is still valid and let's you in. So as like with your gym card, a cookie with your session_id only works with a specific website, like you can not use your gym card to enter office building forexample hte same goes to your cookie, you can not use it log into another different website.

So bank server will keep the session active as long as you keep interacting with the server, if for sometimes you are inactive and after that you visit a new page, the server will notice this period of inactivity and prompt you to provide your username and password again as a security measure.
So the approach mentioned above is called a cookie-based authentication.

Accordingly this approach used a session on the server to handle the authentication.The cookie is only a medium used to transport the sessionID and it is used because it is convinient, the browser will always send a cookie with every request. The same goes with membership_card, It is just convinient to have a card instead of showing you ID everytime but you can probably load the card on your phone and use your phone to get in, so the storage has changed but the concept remains the same, I mean in this case the bank stores the session information on the server side and you cannot see the contents of it but at the same time it can store othe information on the client side on your browser using another cookie forexample: which was the lastpage you visited or what is your preffered font-size or color or anyother less sensitive information.

WHY SERVERS DOES NOT STORE ALOT OF INFORMATION IN THE COOKIES ?

But let's talk about why server doesn't store alot of information in the cookies, this is because the cookies cannot be trusted as they are coming from the client, this is why servers prefer to work with their databases where ideally only valid infromation exists.

An alternative to this is to store information on the client and to sign it, in this scenario anyone holding the signature can quickly check if the data was manipulated or not and one way to do this is to use JSON WEB TOKENS, so basically cookie-based authentication has worked really well for many years but it is slowly becoming outdated atleast in some cases.

Let's say now that you want to install an app on your phone which can help you with your financies and help keep track of your spendings using your bank account information, and what you don't want to do is to give your username and password to this app which is not associated with your bank, in this case your bank will redirect you to your bank account you will give in your username and password and your bank will ask you "hey John would you like to give this app access to your transactions?" and 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. This token is like a randomly generated password if you would wish to say, it like when you we're at the hotel and you get a 1 day wifi password. Am sure you might have seen a similar procedure to this approach anytime you have used Facebook, Google or MicroSoft to grant information for your user profile to a third-party website.
So in this exchange you never exchange you username and password, if you later want you can easily revoke access to your bank account by invalidating the token that was generated. So one of the most commonly used protocols for such scenario's are both openID Connect but also JON WEB TOKENS.

SO YOU ARE PROBABLY WONDERING WHAT IS THE DIFFERENCE BETWEEN A TOKEN AND A SESSION_ID STORED IN A COOKIE:

The difference is that tokens are typically following a standard while sessions are implemented as needed by the server.
Additionally, tokens tend not to need a session on the server but they may have one.

In the case of JWT tokens, the token contain the session information as well, it contains actual data about you as a user.
When using tokens it is essential to notice that now the interaction typically involves multiple parties that may or may not trust one another. So you trust your bank with your bank login{username and password} but you may not trust this third-party app that you found in the AppStore

Another difference is that a token has a limited lifetime and a new token needs to be generated once it expires, the technical term is "refreshed"

A token can also grant access to a subset of data a particular user or entity has, eg: you have only granted access to your transactions but not to other information.

Most of the time tokens are being sent using HTTP headers and not cookies, the reason for that is nowadays many interactions happen out of browsers for-example from apps on your phone and it simply does not make sense to use cookies for that.

"Cookies are sent as HTTP headers but the browsers handles them differently than the other headers"

CONCLUSION

So both session-based/cookie-based and token-based approaches are widespread and typically they are used in parallel for-example a session/cookie based approach is deployed when using the website but token-based approach is preferred when using the app from the same service. So it is essential to understand how both work.

I hope that was useful and now are able to differentiate between cookies, sessions and tokens.

Please if you love my work you can follow my work via :

GitHub
Twitter
LinkedIn
When you support me (by following me) it gives me courage to continue sharing my skills. Thanks

Discussion (38)

pic
Editor guide
Collapse
andreidascalu profile image
Andrei Dascalu

"So the server will store the session information in the database " - what database? Session (even when they exist at all) depend on server side implementations. I haven't heard of one that uses a database by default. Most go to temporary files or in-memory. None that I work with are even able to use a database without third party libraries, at most there's a native option for a k/v store. I would stay away from anything that stores session data to dB.

Collapse
ssimontis profile image
Scott Simontis

ASP.NET's legacy Forms Authentication used to allow using a SQL Server database for session storage, but I believe ASP.NET Core favors in-memory engines, although you are technically free to implement whatever you want if you implement the proper interfaces. For example, using Redis or memcached as a session store provider would alleviate the need for sticky sessions on a load balancer.

Collapse
jaguart profile image
Jeff

I've used MySQL to store user sessions in a small scale system - about 300 simultaneous users. The reason being that with reasonable cache and the use of MyISAM tables, you have lightning fast structured storage of large collections of session data for each user, stored in memory but accessible using a structured query language. I usually store the session details in multi-record format, never as blobs.
It makes it easier to construct tools for your system admins to see exactly what each user is doing in real-time, and even for your admins to assume and safely change the session of a logged in user for accurate real-time support.

Collapse
rendlerdenis profile image
Denis Rendler

Actually lots of languages and specially frameworks offer support for storing the session data in databases. Now there might be a bit of a difference in the way we define a database, but from my perspective even Redis is a db since it allows storing the data long term on disk. I guess the session being stored in dbs is more common in SOA world where you could have several instances of a service being deployed. So, in this case you can either share the session or tag the user to always direct him to the correct instance.

Collapse
jcubic profile image
Jakub T. Jankiewicz • Edited

If you want sessions that are written without cookies you need your own solution for sessions, You can use a database for that. I think that most session solutions use cookies by default.

Collapse
andreidascalu profile image
Andrei Dascalu

Not sure you can have sessions without cookies. Session data is not stored in cookies. Only session identification is passed by cookies. Server side defaults to tmp file stored and configurable to k/v stores.

Thread Thread
jcubic profile image
Jakub T. Jankiewicz • Edited

Yes, you can. You can keep the token in memory or LocalStorage and send it with every request. I'm using something like this with JSON-RPC where the token is the first argument to remote procedure. But as I've said you will need to have your own session mechanism because most default sessions use cookies. And for that you can use the database, of course, you can also use files or both (SQLite that is both file and database).

Thread Thread
andreidascalu profile image
Andrei Dascalu

No, you're talking about a totally different things. Sessions are a concept proper to web servers, where some information related to user activity can be stored server side (in files or k/v stores) and are identified by a web server generated ID. That ID, by default navigates in cookies OR GET parameter (by default SESSION_ID=xxx). That's how sessions work. Some people try to use tokens as session storage in itself, but that in itself is a custom implementation. Using tokens to store session data is wrong. You can use tokens to store session id's, but that's fairly pointless. Tokens are used to store authentication (and authorization, stometimes) to authenticate requests (not to store session data). The issue I was talking about is server side data storage, the kind of that that you can't & shouldn't store client side.
Also, in memory storage is really bad, it's vulnerable to lots of attacks. LocalStorage is also bad (mostly it's also limited so you can't really store the kind of information sessions need) and vulnerable mostly to XSS. Secure cookies are best for storing tokens (though not as a means of communication, you write to cookie, then read to send separately while the server expects the token in dedicated headers and ignores the cookie data).

Thread Thread
jcubic profile image
Jakub T. Jankiewicz

I think you don't u understand what I just wrote and keep changing the subject. First, you said that you can't use the database which is not true because you can use it for the session if you create your own mechanism.

Then you're contradicting yourself because first, you said that you can't have a session without cookies, and then next you said that you can use the GET parameter for the session_ID.

My comment only meant that you can create the session with a database and without cookies. You don't need to rely on whatever the platform gives you.

Thread Thread
andreidascalu profile image
Andrei Dascalu

No man, what I'm talking about is the context of the OP: cookies vs sessions vs tokens, used as means of exchanging information that stores information about user activity. These terms were used under their proper definition (including session, as a server-provided ephemeral storage).
Yeah, sure, you can create your custom system, you can create your custom anything but what I was talking is what you can use to integrate within the sever provided framework (which already manages how clients are identified and whatnot). That's way beyond the topic of using what's provided. My point was merely to correct a statement in the OP which implied that databases are somehow part of the session mechanism (they're not). The session mechanism as per OP is what the server provides you. You could create your own, but that's not the same thing.
Also, the mere fact that something exists doesn't mean it's usable (session id in URL is as exposed as you can get) so I wouldn't consider as something that's in your toolbox.

Thread Thread
kevinmduffey profile image
Kevin Duffey

Andrei is correct.. Jakub seems to miss Andrei's point.

Collapse
dev_emmy profile image
nshimiye_emmy Author

Yeah, I think that's the reason as to why cookie-based authentication is not that much used nowadays. Most applications use token based authentication

Collapse
andreidascalu profile image
Andrei Dascalu

Not sure that's the real alternative. Sessions need to be stored somewhere server side (while tokens don't) but token are also stored in cookies (just not sent via cookies)
Client side it's the same type of problem. You need to store the session Id or the token somewhere on the client before it's sent back to server, preferably in a way that's protected against xss and csrf.

Thread Thread
dev_emmy profile image
Thread Thread
codingsafari profile image
Nico Braun

When using tokens, you still need to maintain a "deny-list" on the backend, with tokens that have been revoked. The overhead is significatly lower than maintaining all the sessions though.

Thread Thread
dev_emmy profile image
Thread Thread
andreidascalu profile image
Andrei Dascalu

Not necessarily, since tokens expires. You can, if you want to, but you don't have to. Tokens should have short lifespans like a few minutes and extend their lives through refresh. You don't need to revoke a token for a few minutes, just flag the account to temporarily deny renewal.

Thread Thread
codingsafari profile image
Nico Braun • Edited

usually its more than a few minutes and usually yes you certianly revoke the token as soon as the user clicks logout. You are not going to let the token be valid. And thats just the scenario where probably nothing bad will happen. Sometimes you may know that a token is comprimised and you need to revoke. Even few minutes then can cause damage.

Thread Thread
andreidascalu profile image
Andrei Dascalu

well, like I said, it's up to how you design your application and what concerns you have there. Suffice to say it can be nice to have, but it's not a universal requirement, not by a longshot.

Thread Thread
dev_emmy profile image
nshimiye_emmy Author

yeah, it all depends on how you want to design your application

Collapse
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 :)!

Collapse
codingsafari profile image
Nico Braun • Edited

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.

Collapse
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

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.

Collapse
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.

Collapse
Collapse
jcubic profile image
Jakub T. Jankiewicz • Edited

"SESSION STORED IN A COOKIE" session is never stored in the cookie and there is more to tokens than JWT. The token can be an identifier that is saved in a cookie that matches the session on the server. So you can have all your cases as one case.

Collapse
dev_emmy profile image
nshimiye_emmy Author

I did not say that "SESSION STORED IN A COOKIE" instead if you read well I said "Session data is stored on the server side, but a seession_id is stored on client side in a cookie. It allows the server to match a given user with the right session data""

Collapse
jcubic profile image
Jakub T. Jankiewicz

Please read it again, this is the section title copy/paste from the article I didn't wrote this down:

SO YOU ARE PROBABLY WONDERING WHAT IS THE DIFFERENCE BETWEEN A TOKEN AND A SESSION STORED IN A COOKIE

Thread Thread
dev_emmy profile image
nshimiye_emmy Author • Edited

ohhh sorry about that, updated. thx

Collapse
jcubic profile image
Jakub T. Jankiewicz

I'm not sure if you're aware but SESSION_ID is a form of a TOKEN. Unless you talk specifically about JWT. See Wikipedia it even have session token redirect to Session_ID en.wikipedia.org/wiki/Token

Collapse
lazerg profile image
lazerg

Great article

Collapse
dev_emmy profile image
Collapse
ayushhdwi profile image
Ayush Dwivedi

Thanks for the artical, it was really helpful and wonderfully explained !!

Collapse
dev_emmy profile image
nshimiye_emmy Author

thank you so much! I really appreciate that.

Collapse
bruce_taotao profile image
bruce_taotao

Usefully~

Collapse
labn36 profile image
Rishabh Agrawal

thanks for clarity @dev_emmy