Single Page Applications are become the standard of the web development architecture. One of the best methods to authenticate a user is by using JWT web token, so first of all, let’s see a general view of what is it and when you should use it!
What’s JWT token?
JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.
It consists of three parts separated by dots (
.), which are:
- Header: A JSON(Base64 encoded) that has info about algorithm used(like HS256, RSA) and so on.
- Payload: A JSON(Base64 encoded) that has info about the user.
- Signature: a signed string generated by the header algorithm by joining the encoded header, the encoded payload and a secret.
Therefore, a JWT typically looks like the following:
JWT Tokens vs Cookies
As a stateless Single Page Application, after you login (via username/password, OAuth 2, etc), for every future API request, the server must need to know who you are in order to perform authenticated/authorized actions.
The are 2 main ways to identify a client in your REST API:
- Session Cookie
- Auth Token
Both of them offer many pros and cons:
- They are stored by the browser with a related expires date and associated domain.
- If the user closes the browser, the cookie will be deleted and he is no longer logged in.
- Using the Secure option the cookie will be stored only if the request has been sent over a secure channel (HTTPS).
- Using the SameSite option it will not send with cross-site requests. This protect your API from CSRF attack.
- The SameSite option is not supported by all browsers, so you cannot completely trust it.
- If the cookie is not created by HttpOnly option it is vulnerable to the XSS attack, so an attacker could steal user session cookie.
- The cookie will be sent over cross-site requests and to avoid CSRF attack you should use the CSRF token for each request.
- It store a session inside the server.
- Server has just to verify the token validity in order to authenticate a user, it doesn’t need to ask to a database.
- It works the same for both native mobile apps and browser clients.
- If you store the token inside the local storage you don’t worry about CSRF attack.
- If you store the token into cookies it is also vulnerable to CSRF attack.
At this point the main issue using JWT is where to store it in order to avoid the XSS and CSRF attacks.
Storing JWT Token: The Cookie and Local Storage Approach
I was inspired by Peter Locke post https://medium.com/lightrail/getting-token-authentication-right-in-a-stateless-single-page-application-57d0c6474e3 where he explains how to store token into 2 cookies but mine approach is a little bit different.
The main idea is to split the JWT token into 2 parts, but instead of using 2 cookies and after that use CSRF token for each request I store Header and Payload into the local storage and the Signature into a Session Cookie with HttpOnly option set to true.
The server has to rebuild the token before validate it, so the approach became the following:
This solution solves all security issues, avoid to create a CSRF token for each request and maintain a stateless application.
If you liked this post feel free to leave a comment about it and don’t forget to clap!