Mastering JWT Authentication: A Deep Dive into Access Tokens and Refresh Tokens
Hey Hashnode community! π In today's blog post, we're going to learn on a JWT authentication concept, focusing specifically on Access Tokens and Refresh Tokens. Gain a deep understanding of how these tokens play a crucial role in securing our applications. Maybe in the upcoming blogs i will write a very detailed blog on how to use JWT + Access Tokens + Refresh Tokens for user login & user registration.
If You Don't have time just read this section
Access Token:
It is a JWT token.
It is short lived (15min, 30min, 1Day, etc.)
It is created after the user is logged in.
It is stored in cookies of user's browser, not in the database.
When a user is doing any kind of operation on web platform that needs the user to be logged-in to perform that task, like say:
Liking a photo of someone (user need to be logged-in to perform this)
Changing their username, password, profile picture, deleting their account, creating a new post (instagram for example) etc.
You see these are the tasks that need the user to be logged-in, so to know if the user is logged-in or not, we take the access token from the user's browser cookie and know if the user is logged-in or not.
If the user is found to be logged-in only then, we will let them perform these tasks on our platform.
As long as Access Token is not expired, user can perform any task⦠the logged in user can perform on the server, when the access token is expired the access is revoked & new access token needs to be created again.
Refresh Token:
It is also a JWT token.
It is long lived (1Day, 2Day, 10Day, etc.)
It is stored in cookies of user's browser + some database like mongoDB, SQL.
It is used to re-generate the expired access token.
When we come to know that the access token in user's browser cookie is expired, we regenerate the access token from the refresh token.
One method to do this is go to the user's browser cookie and take the refresh token and then use that token to regenerate the access token. When the access token is generated, we replace the expired access token in the cookie of user's browser with this new access token.
This was it for the, below is more detailed knowledge.
Understanding JWT Authentication
JSON Web Tokens (JWT) have become a popular choice for authentication in web development due to their simplicity, security, and scalability. They consist of three parts: a header, a payload, and a signature. In the context of authentication, we are particularly interested in the payload, which carries information about the user.
For NodeJS there are three famous libraries that implement JSON WEB TOKENS:
npm install jsonwebtoken (most famous, i use this)
npm install jose
npm install aws-jwt-verify
The Role of Access Tokens
What are Access Tokens?
Access Tokens are like VIP passes for your users. Once a user successfully logs in, the server generates an Access Token and sends it back to the client. This token is then included in the headers of subsequent requests to access protected resources.
Anatomy of an Access Token
An Access Token typically contains information such as the user's ID, roles, and expiration time. Its content is encoded, not encrypted, making it easy to decode on the client side. However, the signature ensures that the token remains tamper-proof.
Securing Access Tokens
To enhance security, always transmit Access Tokens over HTTPS. Additionally, consider short expiration times to minimize the window of opportunity for potential attackers. You just do all this in a .env file. For example:
You see just add 1d (means 1 day), 10d (means 2 days) to represent the expiration time in a .env
it is that easy.
Code For Creating JWT
This code actually comes from my personal open source project in which i am implementing a complex backend inspired from YOUTUBE.
Link to my project: https://github.com/navraj-singh-dev/mega-project-javascript-backend
A mongoose schema is made, then .methods
object is used that is given by mongoose to be used on a mongoose schema and a new methods can be put into that .methods
object.
In this code i create a JWT Token and to create a token a payload (fancy name for data) is given, i gave the user's _id, email, fullName, username for example. The a secret key, then a expiry date is given. That's It.
You don't need to do exactly like this, but you also can do this exactly like this too, you can just create a simple function and call that function to do this operation.
userSchema.methods.generateAccessToken = function () {
return jwt.sign(
{
_id: this._id,
email: this.email,
username: this.username,
fullName: this.fullName,
},
process.env.ACCESS_TOKEN_SECRET,
{
expiresIn: process.env.ACCESS_TOKEN_EXPIRY,
}
);
};
Introducing Refresh Tokens
What are Refresh Tokens?
Access Tokens come with a limited lifespan. Refresh Tokens, on the other hand, are long-lived tokens designed to obtain a new Access Token when the original one expires. They are stored securely on the client side(browser is called client side) and are used to request a fresh Access Token without requiring the user to log in again. The refresh token is no different from access token, refresh token is 99% same as access token, refresh token just have long expiry date than access token. Otherwise, refresh token is JWT token which is created exactly like how access token. Code is 100% same to, just expiry date is different.
Enhancing Security with Refresh Tokens
Since Refresh Tokens have a longer lifespan, their compromise poses a greater risk. Secure storage mechanisms, such as HTTP-only cookies and secure attributes (look in the code), help mitigate this risk.
// make cookie secure by enabling these options
const cookieSettings = {
httpOnly: true,
secure: true,
};
/*
this below code will set the cookies in user's browser.
it will make 2 cookies, for access & refresh token.
backend will take access & refresh tokens these cookies.
these access & refresh tokens are used to know is the user logged-in?
is the user valid?
etc. etc.
*/
return res
.status(successResponse.statusCode)
.cookie("AccessToken", accessToken, cookieSettings)
.cookie("RefreshToken", refreshToken, cookieSettings)
.json(successResponse);
}
Token Rotation Strategies
Token rotation involves invalidating the old Refresh Token and issuing a new one after each use. This strategy reduces the risk of long-term token misuse.
Implementing JWT Authentication in Practice
Server-Side Implementation
User Authentication: Authenticate users and generate a JWT Access Token and Refresh Token upon successful login.
Access Token Validation: Verify the Access Token's signature and decode the payload to extract user information on every protected resource request.
Refresh Token Usage: When the Access Token expires, use the Refresh Token to obtain a new Access Token without requiring user credentials.
Token Rotation: Implement token rotation strategies to enhance security.
Client-Side Implementation
Token Storage: Store tokens securely in browser of user with HTTP-only cookies.
Token Refresh Handling: Implement logic to automatically refresh the Access Token using the Refresh Token when necessary.
Conclusion
Understanding the Access Tokens and Refresh Tokens is great for implementing secure authentication in your applications. By following best practices, and staying informed about the latest developments, you can build authentication systems that protect user data.
Feel free to share your thoughts, experiences, or questions about JWT authentication and token management in the comments below. Happy coding! ππ»
#JWTAuthentication #WebSecurity #AccessToken #RefreshToken #HashnodeBlog