Using JSON Web Tokens (JWT) for authentication and session data
Many articles explain how to scale web applications. Most of them are focused on high performance hardware, extensive caching, and configuration-related topics like how to optimise servers, build more efficient database queries, and set up complex infrastructure. All of these things need a lot of additional resources such as system administrators and so on.
Instead, this article addresses one of the first steps when it comes to the initial design of your application: authentication, sessions, and cookies. Interested in what this has to do with scaling?
The common way to handle requests in a web application is Server Based Authentication:
- A user enters a URL in the web browser
- The web browser sends a request to the web server
- The server processes the request and returns a response to the user’s browser
- While processing the request, the server starts a session 1, issues a cookie 2 containing the generated session id and includes the cookie in the response
- The next request from the user will contain this cookie so that the server can authenticate the session and access the stored information
Besides the well-known security issues with session and session cookies (eg. session fixation 3, session hijacking 4, CSRF or XSRF 5 etc.), there are other considerations that must be made. By design, HTTP 6 is stateless, 7 but with the use of sessions and session cookies, your application becomes stateful, so you need to make sure every request from the same client goes to same web server when your application saves the sessions locally on the server (e.g. filesystem, local database) 8.
Of course, there are several ways to handle this issue such as session sharing. This means you put your database server (e.g. Redis, MySQL) on a separate machine and every web server handling your application can save the sessions to and read them from there. But using this approach only switches the problem from the web server to the database server which will then become the bottleneck. Doing it this way will means you need to scale your machines vertically (“scale up” 9) at some point.
Imagine you want to start a company with limited budget and resources. The internet gives everyone the opportunity to offer their services to a global audience right from the beginning. Scaling not only means building a bigger, high-performance, clustered infrastructure to handle more and more requests, it also means servers running on different locations depending on your company’s target markets, separate machines for internal tasks (e.g. analytics, business intelligence) and different front-ends (e.g. website, mobile app) accessing the same data resources. To achieve this right away with a limited budget, you can make use of several small machines or inexpensive public cloud hosting services from different countries / regions all over the world.
We need a way to build applications without the use of Server Based Authentication. Just to be clear, cookies and server-side sessions are not a bad thing, but they are not easy to use and handle when it comes to scaling, flexibility, and security. We need to be able to scale horizontally (“scale out”) as much as possible, even with small servers. Also, the application should become stateless – every request should be independent from the requests before.
JWT to the rescue
Start building your applications based on JSON Web Tokens (JWT) 10 instead of server-side sessions. Take a look at this great article by scotch.io 11 for a detailed technical explanation about JWT.
What about security?
A JWT is signed. Of course, the content of the token can still be manipulated by the client, but in this case the token will be rejected by the server because the signature of the content doesn’t match the signature of the token anymore and correct signatures can only be generated using your secret application. Do note that the payload (content/session data) of a token is in clear text. The user cannot manipulate the content, but they can read it. If you want/need to avoid this, you must encrypt the token before you send them to the client.
JWTs also have another great benefit: It’s easy to deal with cross-domain/CORS12 because JWTs are not tied to the domain like a session cookie. For example if you serve your website from different servers depending on the region/country and the routing is done on the DNS level by different TLDs, by using session cookies, you are unable to keep a user logged in after they switch from the website of one region to another. With JWT you only need to make sure to the token is in the request. In doing so, the new server has all informations it needs because the session data is in inside the token.
Scaling web applications is a complex topic with a lot of different facades. It is always a combination of multiple actions, tasks and decisions on different levels of your application and infrastructure. Using JWT is just a single step forward, but it also influences the way you set up other parts of your infrastructure. In general, with JWT instead of server-side sessions and session cookies, it becomes easier to configure CDNs, proxy servers, cache engines, loadbalancer etc. because of every request can be fully stateless.
About the author
Benjamin Alsleben is a passionate Software Developer with 5+ years of experience within the web industry. He specialises in backend development for eCommerce systems but also likes to work on various other applications and projects backed by interessting ideas, technologies and business models.
Benjamin is a certified Magento Certified Developer.
- IETF Draft: JSON Web Token
- The Ins and Outs of Token Based Authentication
- 10 Things You Should Know about Tokens
- Cookies vs Tokens. Getting auth right with Angular.JS
- https://en.wikipedia.org/wiki/HypertextTransferProtocol#HTTP_session ↩
- https://en.wikipedia.org/wiki/HTTP_cookie ↩
- https://en.wikipedia.org/wiki/Session_fixation ↩
- https://en.wikipedia.org/wiki/Session_hijacking ↩
- https://en.wikipedia.org/wiki/Cross-siterequestforgery ↩
- https://en.wikipedia.org/wiki/HypertextTransferProtocol ↩
- https://en.wikipedia.org/wiki/Stateless_protocol ↩
- https://en.wikipedia.org/wiki/Loadbalancing%28computing%29#Persistence ↩
- https://en.wikipedia.org/wiki/Scalability#Horizontalandvertical_scaling ↩
- https://en.wikipedia.org/wiki/JSONWebToken ↩
- https://scotch.io/tutorials/the-anatomy-of-a-json-web-token ↩