Difference Between Access Token and Refresh Token

Access Token :-

By checking the access token we allow users to access the functionality of our app for example you are using a social media app and you have logged in successfully . Now when you are trying to comment or like on any post then your access token is checked that you are authorized or not . and every token has expiry if your access token is expired then you will not able to comment or like any post on app and to do so you have to login again so to overcome the problem of login again and again we use refresh token.

Refresh Token :-

Refresh token is used to update your access token so that you don't need to login again after the expiry of your old access token to access the features of app.

The refresh token is a more long-term key that you can use to get a new access token without having to enter your username and password again. It's like having a master key to get new temporary keys.

So, when your access token expires, you can send the refresh token to the server along with a request asking for a new access token. If the refresh token is still valid and hasn't expired, the server issues you a fresh access token without requiring you to log in again.

Code:-

first, let's set up a scenario where a user logs in and receives both an access token and a refresh token.

const express = require('express');
const jwt = require('jsonwebtoken');

const app = express();

// Secret key for signing tokens
const accessTokenSecretKey = 'mysecretkey1';
const refreshTokenSecretKey = 'mysecretkey2';

// Route for user login
app.post('/login', (req, res) => {
    // Assuming user authentication successful
    const loggedInUser = { username: 'example_user' };

    // Generate an access token (expires in 15 minutes)
    const accessToken = jwt.sign({ _id: this._id }, secretKey, { expiresIn: '15m' });

    // Generate a refresh token (expires in 7 days)
    const refreshToken = jwt.sign({ _id: this._id }, secretKey, { expiresIn: '7d' });

    // Send the access token and refresh token as cookies
    res.cookie('accessToken', accessToken, { httpOnly: true });
    res.cookie('refreshToken', refreshToken, { httpOnly: true });

    res.json({ message: 'User logged in successfully' });
});

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});
  • When a user logs in (/login endpoint), we generate both an access token and a refresh token using the jsonwebtoken library.

  • We set both tokens as cookies in the HTTP response using res.cookie(). Notice the httpOnly: true option for added security.

  • The access token is set to expire in 15 minutes (expiresIn: '15m'), while the refresh token is set to expire in 7 days (expiresIn: '7d').

// Route to refresh access token using refresh token
app.post('/refresh-token', (req, res) => {
    const refreshToken  = req.cookies?.refreshToken;

    //if refreshToken not exist means user is not logged in
    if (!refreshToken) {
        throw new error("Unauthorized Access");
    }
    // Verify the refresh token
    const decodedToken = await jwt.verify(token, refreshTokenSecretKey);

    //User is a mongoose schema
    const user = await User.findById(decodedToken._id);

    //if user not exist means refresh token expired or used or invalid
    if (!user) {
        throw new error("Invalid refresh token");
    }

    //make new access token
    const accessToken = jwt.sign({ _id: this._id }, accessTokenSecretKey, { expiresIn: '15m' });

    //save to cookies
    res.cookie('accessToken', accessToken, { httpOnly: true });

    res.json({ message: 'Access token refreshed successfully' });
});
  • We extract the refresh token from the request cookies.

  • We verify the refresh token using the same secret key used for signing.

  • If the refresh token is valid, we generate a new access token and send it as a cookie in the HTTP response.

This way, the user can refresh their access token without having to log in again, as long as the refresh token is still valid.