DEV Community

JAGADEESH m
JAGADEESH m

Posted on

JWT Token Refresh: Authentication Made Simple πŸ”

Why Do We Need Token Refresh?

Imagine you're playing an online game, and every 30 minutes, you get kicked out and have to log in again. Frustrating, right? In web applications, authentication works similarly. Tokens (like digital passes) expire for security reasons, but we want to make this process smooth for users.

The Problem with Traditional Authentication

When a token expires, most applications force you to log in again. This is like being midway through a task and suddenly being told to start over from scratch. Our goal is to fix this!

How Token Refresh Works: A Simple Explanation

Think of Tokens Like a Day Pass

  1. Access Token: A short-lived ticket that lets you enter different parts of an application
  2. Refresh Token: A special, longer-lasting ticket that helps you get a new access token

Image description

The Magic Happens in Two Steps

Step 1: Detect Token Expiration

// When a request fails because the token is old
Client.interceptors.response.use(
  (response) => response, // Normal responses pass through
  async (error) => {
    // Check if the error is because the token is expired
    if (error.response?.status === 401) {
      // It's like saying, "Oops, my pass is old. Let me get a new one!"
      const newToken = await refreshToken();
    }
  }
)
Enter fullscreen mode Exit fullscreen mode

Step 2: Get a New Token

const refreshToken = async () => {
  try {
    // Ask the server for a new access token
    const response = await Client.post("/auth/refresh", {
      withCredentials: true // Important security detail
    });

    // Extract the new token
    const { accessToken } = response.data;

    // Update the application with the new token
    updateToken(accessToken);

    return accessToken;
  } catch (error) {
    // If getting a new token fails, log the user out
    console.error("Couldn't refresh token");
    return null;
  }
};
Enter fullscreen mode Exit fullscreen mode

The Secret Sauce: Remembering the Original Request

// This is the magical part - saving the original request
const originalRequest = error.config;

// After getting a new token, replay the exact same request
if (newToken) {
  // It's like rewinding and replaying a game level
  originalRequest.headers.Authorization = `Bearer ${newToken}`;
  return Client(originalRequest);
}
Enter fullscreen mode Exit fullscreen mode

Real-World Analogy

Think of this like a multi-pass at an amusement park:

  • Your access token is a single-ride ticket
  • Your refresh token is the ability to get a new ride ticket
  • When a ride ticket (access token) expires, you use the multi-pass (refresh token) to get a new one
  • You don't have to leave the park or start over - you just get a new ticket!

Backend: Verifying the Refresh Token

const refresh = async (req, res) => {
  try {
    // Check if the refresh token exists
    const refreshToken = req.cookies.refreshToken;

    // Verify the token is valid and belongs to a real user
    const payload = jwt.verify(refreshToken, process.env.JWT_SECRET);

    // Find the user
    const user = await User.findOne({ email: payload.email });

    // Create a new access token
    const accessToken = jwt.sign({
      username: user.username,
      email: user.email
    }, process.env.JWT_SECRET, { expiresIn: "1d" });

    return res.status(200).json({ accessToken });
  } catch (error) {
    // Something went wrong
    return res.status(401).json({ message: "Authentication failed" });
  }
};
Enter fullscreen mode Exit fullscreen mode

Key Takeaways

  1. Token refresh keeps users logged in seamlessly
  2. We save the original request to replay it after getting a new token
  3. The process happens automatically in the background
  4. Users never know their token was refreshed

Pro Tips

  • Always use HTTPS to protect tokens
  • Implement proper error handling
  • Have a backup plan if token refresh fails

Conclusion

Authentication doesn't have to be complicated. With the right approach, you can create a smooth, secure experience that keeps your users happy and your application protected.

Happy Coding! πŸš€πŸ”

Top comments (0)