Senin, 16 Juni 2025

Access and Refresh Token Explained

| Senin, 16 Juni 2025

While building an application or authentication system, it's crucial to ensure that users have access only to the data they are authorized to view, and each access must be granted to verified users only. Unauthorized access to your data can raise concerns about your application's workflow and authenticity. OAuth 2.0 and OpenID Connect are two protocols that introduce security measures and token-based authentication for applications, adding a security layer to your application. These measures help make accessing your application data a secure and authentic process. The tokens used for this process are Access Tokens and Refresh Tokens.

How Access token works //image from medium

Access Token

An access token is a short-lived token used to access data in your application. Whenever a user requests data, this token is verified for accessing the data. Generally, it is stored in-memory (not in LocalStorage or a database) to enhance security. The lifespan of an access token is typically a few minutes or seconds. This short lifespan minimizes the risk of misuse if the token is compromised.

Access Tokens are typically added to API request headers as authHeader, and this value is shown as Bearer -accessToken-. This is the standard method for using Access Tokens in applications and for making requests with an Access Token.

Here are the functions where we implemented the generation and verification of Access Tokens in JavaScript.

// generateToken function to generate Access Token in your NodeJS Application
const generateAccessToken = (user) => {
  return jwt.sign(
    { id: user.id, email: user.email }, // payload
    process.env.JWT_SECRET,
    { expiresIn: process.env.JWT_EXPIRES_IN } // generally 5min or 60 sec
  );
};
// function to verify your access token and give access to you in application
const verifyToken = (req, res, next) => {
  const authHeader = req.headers.authorization;

  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    return res.status(401).json({ message: 'Access token missing or invalid' });
  }

  const token = authHeader.split(' ')[1];

  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded;
    next();
  } catch (err) {
    return res.status(401).json({ message: 'Invalid or expired token' });
  }
};

As you can see, the Access Token is generated with payloads, verified, and then grants the user access to the next process they requested.

Refresh Token

How Refresh Token works // image from gfg

A refresh token is a long-lived token used to generate new access tokens after the expiration of an access token. It is stored securely in a database and user storage. After the access token expires, the application verifies the refresh token against the database. Upon successful verification, new access and refresh tokens are generated, providing the user with continued access to the requested data.

Here are the functions to generate and verify a refresh token.

// function to generate Refresh Token
const generateRefreshToken = (user) => {
  return jwt.sign(
    { id: user.id },
    process.env.JWT_REFRESH_SECRET,
    { expiresIn: process.env.JWT_REFRESH_EXPIRES_IN } // generally 7d
  );
};
// function to verify refresh token and generate new Access Token
function verifyRefreshToken() {
  try {
    const decoded = jwt.verify(refreshToken, process.env.JWT_REFRESH_SECRET);
    const newAccessToken = generateAccessToken({ id: decoded.id, email: decoded.email });
    res.json({ accessToken: newAccessToken });
  } catch (err) {
    return res.status(403).json({ message: 'Refresh token expired or invalid' });
  }
});

In the code snippet, you can see that the refresh token is created with minimal information, like the ID, because it's only needed to verify the user, not to access resources. During verification, the refresh token is checked, and after successful verification, a new access token is generated to provide the user with access to the resource.

Key Aspects of Access and Refresh Token

The key aspect of the separation between access and refresh tokens lies in the possibility of making access tokens easy to validate. An access token that carries a signature (such as a signed JWT) may be validated by the resource server on its own, without needing to contact the authorization server.

Refresh tokens, on the other hand, require access to the authorization server. By keeping validation separate from queries to the authorization server, better latency and less complex access patterns are possible.

Appropriate security in case of token leaks is achieved by making access tokens as short-lived as possible and embedding additional checks (such as client checks) into them. Refresh tokens, by virtue of being long-lived, must be protected from leaks. In the event of a leak, blacklisting may be necessary in the server (short-lived access tokens force refresh tokens to be used eventually, thus protecting the resource after it gets blacklisted and all access tokens are expired).

Conclusion

In conclusion, implementing access and refresh tokens is a fundamental aspect of securing your application's data access processes. By understanding the distinct roles and lifespans of these tokens, developers can ensure that only authorized users gain access to sensitive information, thereby maintaining the integrity and security of the application. The strategic use of short-lived access tokens and long-lived refresh tokens, along with robust validation mechanisms, helps mitigate risks associated with token leaks and unauthorized access.

As a result, these practices not only enhance security but also improve the overall user experience by providing seamless and secure access to application resources.


Related Posts

Tidak ada komentar:

Posting Komentar