The Need to Secure Your Single Page Application
Many are adopting a new approach with the rise of single page applications (SPA) and modern client-side frameworks to support it like Reat, Angular or Vue. They create separate architecture for building applications, in which they build an API to handle business logic and move presentation layers to the front-end completely. This approach allows them to have a clear separation between backend and front end. Furthermore, it is beneficial in scalability in addition to building breakthrough user experiences. In conclusion, this approach is better known as the JSON web token approach. But this approach also poses a very important question: How do you authenticate the users of your SPA? The most popular solutions for this is using cookies-based or JSON web token-based authentication.Cookies-Based Authentication
Before token, many systems were using a cookies-based method to handle authentication. Cookies-based auth is stateful, meaning you have to keep an authentication record on both the server and the client’s side in order to hold the state of user authenticity. Furthermore, a simple cookies-based authentication flow looks something like this:- Users input their credentials (username, password, etc.) and send a request for authentication.
- After the request is made, the server verifies the correctness of the credentials and creates sessions for the ones that turned up valid. Therefore, these sessions are stored in a storage engine (i.e. a database).4
- The response header receives returned session IDs.
- The user’s browser stores a cookie with the session ID.
- On subsequent requests, the session ID is verified against the database and if valid the request is processed.
- Destroy the session in both the client and the server side when a user logs out of the app.
Token-Based Authentication
Cookies and sessions are not used when it comes to JSON web token-based authentication. As a result of this, it relies on a signed token that is sent to the server on every request. This JSON web system requires users to enter their usernames and passwords once. Then, it generates a time-limited signed token and sends it back to the client side. From this point, every request to the server is accompanied by this JSON web token which the server uses to verify the authenticity of the request.Why Do We Need Token?
Some benefits of choosing token over a cookies-based approach:
Stateless: This means the server does not need to store any authentication record. The token is a self-contained entity and it contains all of the information it needs in order to identify the user. The job of the server is only signing the tokens on successful login requests and verifying the validity of incoming tokens. Cross Domain & CORS: Using token can eliminate all of the troubles you encounter when it comes to dealing with cookies across different domains. Client-Independent: Since the token is sent via a request header, you can send requests to your API using any type of clients that makes HTTP requests. Performance: With the token, you can store additional information like user’s permission levels inside JWT, which reduces heavy lifting lookup operations on the server.JSON Web Token (JWT)
JSON Web Token stems from a standard token-based approach. “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.” – jwt.io In conclusion, a JWT generally consists of 3 parts: Header, Payload and Signature. Header and Payload are Based64 encoded and linked by a period character. Finally, the result is an algorithmic signature that produces a token in the form of header.claims.signature. See the structure below:header.payload.signature
Create a JWT Token
Finally, let’s go through this step-by-step tutorial on how to create a sample JWT token:Header
The header is a JSON object that contains the information on how we generate the JWT signature. As a result, it typically consists of 2 parts: the token type and the hashing algorithm. Example of a header:{ "alg": "HS256", "typ": "JWT" }Base64Url encoding this JSON will give us the first part of our JWT, a header should look something like this:
// header eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Payload (or JWT Claims)
The Payload contains the claims we wish to make. Typically, this is where we put the information we want to transmit (i.e. a statement about a user) and additional metadata about the token itself. As a result of this, there are 3 types of claims:- Registered Claims: These are a set of recommended predefined claims. They provide a set of useful, inter-operable claims:
- iss: The issuer of the token
- sub: The subject of the token
- aud: The audience of the token
- exp: Many use this registered claim often. This defines the expiration in NumericDate value. The expiration MUST be after the current date/time.
- Public Claims: These can be defined at will by those using JWTs. But to avoid collisions they should be defined in the IANA JSON Web Token Registry or be defined as a URI that contains a collision resistant namespace.
- Private Claims: Parties who agree on using private claims share them between each other to create custom claims.
{ "sub": "1234567890", "name": "John Doe", "admin": true }Base64Url encoding this JSON gives us the second part of our JWT. A payload should look something like this:
// payload eyJzdWIiOiAiMTIzNDU2Nzg5MCIsIm5hbWUiOiAiSm9obiBEb2UiLCJhZG1pbiI6IHRydWV9
Signature
Compute the signature based on header and payload values. See in the following steps below:- Header & Payload (see above) will be based64 encoded.
- Use . character to link these two characters and to form a new string.
- The new string is hashed with a secret_key using a hashing algorithm that is defined in the JWT header.
encodedData = base64UrlEncode(header) + "." + base64UrlEncode(payload); signature = HMACSHA256(encodedData, 'secret');
Finally, Let’s Put Them All Together
This part is rather simple, we just need to follow the header.payload.signature structure by combining all 3 components using the period “.“. Finally, this is how a JWT token looks:// a JWT token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQCongratulations! Now, you can take your JSON web token authentication skills to a whole new level. We hope this coding tutorial has been helpful and for additional tutorials and news on the latest tech trends, be sure to visit Pangara’s blog. Are you ready to take your skills to a recruiter? Before you begin, don’t forget to take a peek at our helpful tips to keep in mind throughout the recruitment process. Good luck!