Introduction
In web development, knowing authorization and authentication mechanisms is essential for developers to understand. The popular methods to handle this procedure are JSON Web Tokens (JWT) and cookie storage.
This post will review the definitions, structures, advantages, and disadvantages of JWT and cookie storage. Finally, we will compare the two to help you decide which is best for your project.
What is a JWT?
A JWT is a proposed standard for making data with a signature and/or encryption that holds JSON with claims. The tokens are signed using a secret (with the HMAC algorithm) or a public/private key using RSA or ECDSA.
JWT Structure
A well-compacted formed JSON Web Token consists of three concatenated Base64url-encoded strings, separated by dots (.):
The JWT Header: It contains metadata about the type of token and the cryptographic algorithms used to secure its contents. for example;
{
"alg": "HS256",
"typ": "JWT"
}
- The JWT payload: The second part of the token is the payload, which contains the claims. Claims are statements about an entity (typically, the user) and additional data. There are three types of claims: registered, public, and private claims:
- Registered claims: These are a set of predefined claims which are not mandatory but recommended, to provide a set of useful, interoperable claims.
- Public claims: These can be defined at will by those using JWTs. To avoid collision they can be defined as a URL that contains a resistant namespace.
- Private claims: These are the custom claims created to share information between parties that agree on using them and are not registered as public claims. for example, the payload could be like this;
{
"sub": "1234567890",
"name": "user",
"admin": true
}
- The JWT signature: The signature is used to verify the message wasn't changed along the way, and, in the case of tokens signed with a private key, it can also verify that the sender of the JWT is who it says it is.
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
The output can be easily passed into an HTML or HTTP environment.
A typical JWT appears as follows:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6ImV4YW1wbGVfdXNlciIsImlhdCI6MTUxNjIzOTAyMn0.eAuqcdegpATdo_fsYMBjJZAGi7hEa_Qba_RDvFnBKSI
Common uses for JWT
Here are some scenarios where JSON Web Tokens are useful:
Information Exchange: Sending and receiving information securely between parties can be accomplished with JSON Web Tokens.
Authentication: This is to identify users and restrict them via particular endpoint functions. if it's successful, the server will generate a JSON web token as a response to the client.
Authorization: When a client logs in, a server that uses JWT for authorization will generate a JWT. Since this JWT has been signed, no other party may change it.
The main use of JWT is authentication. As long as valid users are still logged into their respective platforms and each API request doesn't demand continuous credential verification, users don't have to constantly verify their identities for every API call because services offer tokens with user data upon login.
The above image process is explained below;
- The client requests authorization to the authorization server. This is always performed through different authorization flows.
- When the authorization is granted, the authorization server returns a web token to the client's applications.
- The application uses the web token to access protected resources or information (like an API).
Code implementation
This section explains the code implementation of how to set JWT on your website. This can be done with several languages of your choice.
The code used here is for the PHP language.
// Including the dependencies
require_once 'clients/autoload.php';
use \Firebase\JWT\JWT;
// Your secret key to sign the token
$secretKey = 'secret_key_here';
// Payload for the token, containing any data you want to include or share
$payload = array(
"user_id" => 123,
"username" => "example_user",
"exp" => time() + (60 * 60 * 24) // Expiration time, 1 day from now
);
// Generating the JWT to your clients
$token = JWT::encode($payload, $secretKey, 'HS256');
echo $token;
The above code is explained below
require_once 'clients/autoload.php';
: This line of code is to include the autoloader file from the installed dependencies which is the Firebase/JWT library.use \Firebase\JWT\JWT;
: This line of code allows the import of the JWT class from the Firebase JWT library.$secretKey = 'your_secret_key_here';
: This variable is to store the secret key used to sign JWT.$payload = array(...);
: This array contains the claims you want to include in the JWT. This might include the above claims in the example or more. The exp claim is set for 24 which means the Token will expire in 24 hours.
// Generating the JWT to your clients
$token = JWT::encode($payload, $secretKey, 'HS256');
$token = JWT::encode($payload, $secretKey, 'HS256');
: This line of code generates the Token using the encode method of the JWT class.$payload
: The claims to be included.$secretKey
: The secret key used to sign the JWT.'HS256'
: This is the widely used and secure algorithm used for signing the JWT.echo $token
: This code is to output the JWT generated to the screen which can be used for subsequent Authentication and data exchange.
Debugger: Jwt.io
JWT: Best Practices
In the Best practice, users should therefore heed to recommended guidelines that listed below:
Limited scope specifications that limit read/write rights to only those activities that are necessary
Removing old entries regularly reduces cumulative bloat
Implementing HTTPS requirements to prevent spying and eavesdropping
Putting in place strong anti-CSRF defences to strengthen defences against automated exploits.
Advantages and Disadvantages of using JWT
We would look at the pros and cons of using JSON web tokens in your web application;
Advantages of Using JWT
There are benefits to using JWTs.
Stateless Authentication: Stateless nature eliminating reliance upon central databases. This will enable the scaling and load balancing easier because the server does not have to keep track of the session status of each user
Support: Ease of implementation due to readily available libraries supporting diverse programming languages
Authorization: JWTs help servers decide who can do what, like user roles and permissions.
Cross-Origin Resource Sharing (CORS): JWTs in HTTP headers make web apps communicate securely across different origins.
Disadvantages of Using JWT
However, several downsides must be considered before adopting JWT fully:
- Cookie Size Factor: This will cause an increase in the payload size, the size of JWT is larger than the session token and this may negatively impact system performance as a whole.
- Revocable Tokens: Absence of revocation capabilities necessitates either short lifespans prone to frequent refreshes or employing external blacklist registries imposing extra infrastructure costs.
- Security risk: It is vulnerable to XSS attacks unless adequately protected, especially given increased surface areas exposed via single-page applications (SPA).
- Limited Token Updates: JWTs are usually unchangeable once issued. If a user's role or permissions change, they might have to log in again to get an updated token.
What is Cookies storage?
In this section, we will understand what cookie storage is, how it works, and its types, including best practices.
This was introduced first by the Netscape Communications Corporation in 1994.
In every visit to some websites, sites serve "Set-Cookie" headers telling the user's or client browser to save given name-value pairs and optional features that indicate duration. This indicates how long a cookie can persist and under what condition it should be sent to the server. This action allows websites to track user's experiences, preferences, and sessions. In essence 'Set-Cookies' headers are the mechanism by which the website communicates with your browser.
Cookies (also known as browser cookies, HTTP cookies or cookies) are small pieces of information sent back to the user's web browser. They are typically used for Authentication, tracking and personalization.
Cookies storage is a client-side storage where client data are stored.
To view Cookies: F12 → 'Application' → 'Storage' → 'Cookies'
Types of Cookies
These are the primary types of cookies:
Persistent cookies: Are small text files that are stored on a user's computer or device by a website or web application, and they remain there even after the user has closed their web browser.
Session cookies: Track the user's behaviour on the website and help websites identify users browsing through the web pages of a website. The website analytics tool would consider each visit as a new session if it wasn't for session cookies.
Authentication cookies: Are created to help with user's session management when a person logs in with their browser. They ensure that sensitive information reaches the appropriate user sessions by associating user account information with a cookie-identifying string.
Cookies are convenient, but they come with inherent hazards:
That could lead to the leakage of sensitive data and unauthorized manipulation because it can be accessed by unauthorised parties. It's critical to understand authorization and authentication while developing and using cookie storage in any modern website.
It can also be used to track users' behaviours across multiple websites or web browsers, which can result in privacy concerns.
Code Implementation
Also, cookies are code written by the developer to perform some functions on their webpage. Below we have a basic code written in Javascript for cookie storage;
<!doctype html>
<html>
<head>
<script>
function setCookie(cname, cvalue, exdays) {
const d = new Date();
d.setTime(d.getTime() + exdays * 24 * 60 * 60 * 1000);
let expires = "expires=" + d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
function getCookie(cname) {
let name = cname + "=";
let decodedCookie = decodeURIComponent(document.cookie);
let ca = decodedCookie.split(";");
for (let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == " ") {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
function checkCookie() {
let user = getCookie("username");
if (user != "") {
alert("Welcome again " + user);
} else {
user = prompt("Please enter your name:", "");
if (user != "" && user != null) {
setCookie("username", user, 30);
}
}
}
</script>
</head>
<body onload="checkCookie()"></body>
</html>
The above code provides three functions
:
-
setCookie(cname,cvalue,exdays)
: This function sets a cookie by taking the name, the value and the number of days it will take to expire. getCookie(cname)
: This retrieves the value of a specific cookie if exists if not it returns empty.checkCookie()
: This will check if a cookie is set, if a cookie is set it displays a response set by the developer, if not, a prompt box might display asking for the name of the user and store the cookie according to the days set in setCookies function.
Note: Modifications are allowed according to the information of the client you want to store or collect.
Below should be the result:
Cookies Storage: Best practices
When using cookies on a website, there are best practices to follow that can help to ensure that they are used effectively.
Don't store sensitive data in cookies, unless you have to.
Give users the option to opt-out: Developers should give visitors the choice to refuse specific kinds of cookies, like those that are used for tracking or advertising. This can be done by giving the users customised options.
Use secure cookies: Safeguarding important data, like login credentials, developers should use secure cookies. Secure cookies are always encrypted and can only be used with a secure connection (HTTPS).
Provide clear cookies policy: The cookies policy should be explained and checked by the developer, so the users should know the type of cookies being used and they can opt out whenever they want to. check GDPR to know more about the cookies policy.
Review and update cookie policy regularly
Comparison of JWT and Cookies storage
Let's dive into the comparison between the JWT and Cookies storage, with this we will check out the similarities if there are any, and the differences, choosing between the two for authentication or authorization because both JWT and Cookies can be used for Authorization.
Similarities between JWT and Cookies
Authorization are typically sent to the server via an HTTP Request Authorization Header (e.g. Bearer ). Can use Cookie too which is sent to the server in the Cookie request header.
JWT and cookies can be both used for authentication or authorization, A web cookie may be saved in the Cookies storage of your browser and may contain JWT. There are not many similarities between the two.
JWT and cookies storage differences
Even when there may be similarities, there are also differences between JWT and cookie storage. There are several differences compared to the similarities. They rather have differences instead of similarities, below are a few explained differences between JWT and Cookies storage:
Revoking and invalidating: Revoking a user session is easy with cookie, while it's harder to revoke or invalidate a user session in a JWT.
Simpler installation and maintenance: Unlike JWT, cookies don't need extra setup or library installation, which makes them easier to
install and handle.Storage: JWT; the authentication state is not stored anywhere on the server side rather they are saved on the client side, while on the cookie, the authentication is stored on the server side.
the JWT is Stateless, while the cookies are Stateful
Choosing between JWT and Cookies storage
The best alternative option to choose mostly depends on the goals you want to achieve while keeping the targets' convenience, security, and effectiveness in check.
Advertisement: If tracking users is the target for personal advertising cookies storage is the best option to go for as they can keep track of user's browser history or activities.
API Integration: For API integration and resources, JWT performs better in authentication than cookies storage, it controls both the API and client by offering more protection and flexibility.
Data Storage: Any data entered by users can be stored into a form on the website, either login credentials, shopping carts, form date, etc. while JWT cannot perform this functionality.
In choosing either JWT or cookies storage, functionality, needs, and target should be considered before concluding on what to use.
However, JWT can be stored inside Cookie. This method is safer because attackers won't be able to steal your user's token easily. It's also important to know that cookies are not immune to attacks, more security measures should be implemented for the overall security of the application.
Conclusion
When choosing between JWTs and cookies to store authentication tokens, there are certain security tradeoffs to take into account, proper evaluation should also be considered. It also means that an attacker can access the user's account if a JWT or cookies are intercepted or stolen.