Reactjs and Nodejs access/refresh jwt token authentication

I have a problem with the refresh token, login API sends accessToken (expiration: 30s), refreshToken (expiration: 5min), and cookie ‘refreshCookie’ (expiration: 5min). This API works correctly.

login.js (backend)

const express = require('express');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const { promisify } = require('util');
const conn = require('../db_connection');
require('dotenv').config();

const router = express.Router(); // Inizializzazione di un oggetto router
const query = promisify(conn.query).bind(conn); // Permette di far eseguire le query del database in modo asincrono

// Route per il login
router.post('/login', async (req, res) => {
    try {
        const { email, password } = req.body; // Ottieni i dati dal body della richiesta

        // Verifica se l'email è registrata
        const users = await query('SELECT * FROM users WHERE email = ?', [email]);

        // Email non registrata
        if (users.length === 0) {
            return res.status(401).json({ error: 'Utente non registrato' });
        }

        const user = users[0];
        const userId = user.user_id;

        // Verifica se la password è corretta
        const passwordMatch = await bcrypt.compare(password, user.password);

        // Password sbagliata
        if (!passwordMatch) {
            return res.status(401).json({ error: 'La password è sbagliata' });
        }

        // Creazione di un token jwt di accesso
        const accessToken = jwt.sign({ user_id: userId }, process.env.ACCESS_TOKEN_SECRET, { expiresIn: '30s' });

        // Creazione di un refresh token
        const refreshToken = jwt.sign({ user_id: userId }, process.env.REFRESH_TOKEN_SECRET, { expiresIn: '5m' }) 

        // Creazione di un cookie per l'autenticazione dell'utente
        res.cookie('refreshCookie', refreshToken, {
            httpOnly: true, // Accessibile solo da server web
            secure: false, // true = solo https, false = https e http
            sameSite: 'None', // Cross-site cookie (il frontend è su un server diverso)
            maxAge: 5 * 60 * 1000 // 5 min in ms
        });

        res.json({ accessToken, refreshToken });
    } catch (error) {
        console.log("errore login: ", error);
        return res.status(500).json({ error: "Errore durante il login" });
    }
});

module.exports = router;

This API is for the token refresh, when accessToken has expired, the client should send a request at endpoint/refresh-token to get a new access token if refreshToken has not expired.

refresh_token.js (backend)

const express = require('express');
const jwt = require('jsonwebtoken');
const { promisify } = require('util');
const conn = require('../db_connection');
require('dotenv').config();

const router = express.Router(); // Inizializzazione di un oggetto router
const query = promisify(conn.query).bind(conn); // Permette di far eseguire le query del database in modo asincrono

// Route per refreshare il token jwt
router.post('/refresh-token', async (req, res) => {
    const cookies = req.cookies;

    if (!cookies?.refreshCookie) {
        return res.status(401).json({ error: "Utente non autorizzato" });
    }

    const refreshToken = cookies.refreshCookie;

    try {
        const decoded = jwt.verify(refreshToken, process.env.REFRESH_TOKEN_SECRET);

        const user = await query("SELECT * FROM users WHERE user_id = ?", [decoded.user_id]); // Cerca l'utente nel database
        
        // Utente non trovato
        if (!user) {
            res.status(401).send({ error: "Unauthorized" });
        }

        // Creazione di un token jwt di accesso
        const accessToken = jwt.sign({ user_id: decoded.user_id }, process.env.ACCESS_TOKEN_SECRET, { expiresIn: '30s' });
        
        res.json({ accessToken });
    } catch (error) {
        console.log("nErrore refresh: ", error);
        return res.status(403).send({ error: "Forbidden" });
    }
});

module.exports = router;

this is my frontend request, someone could help me to make the client do a request at endpoint/refresh-token when accessToken has expired to get a new access token? I want to use Axios and cookies to save tokens. I want the token to be refreshed only when the old token has expired.

login.js (frontend)

// Funzione che invia una richiesta al server e restituisce la risposta
      async function handleSubmit(e) {
        e.preventDefault();
        try {
            const response = await axios.post(`${config.API_BASE_URL}/api/login`, { formData }, {
                withCredentials: true
            });
            const { accessToken } = response.data;
            Cookies.set('accessToken', accessToken);
            navigate("/");
        } catch (error) {
            console.error("Errore login: ", error);
            setError(error.response.data.error); // Gestisci altri tipi di errore di login
        }
    }

I have tried with Axios interceptor but it doesn’t work, I prefer to use this method.

New contributor

marco.bonaaa is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

3

First of all 30 second seems to me very short. Maybe consider to extend that time.

I guess what you want here is setting a setTimeout or a setInterval. Both are global functions available by js.

Basically you want to do soemthing like this:

Interval (prefered solution)


const delay = 30 * 1000; // time in ms


// Now setting the interval your submit will run every 30 seconds
setInterval(handleSubmit, delay);

To this solution you can also add some sort of checking if the access token is really outdated, if it is not you can wait for it (e.g. using setTimeout).

Timeout (just here as an alternative)

Some people would probably consider this as a valid set up. But I would not reccomend it! But to be complete here would be soutlion using setTimeout.



const delay = 30 * 1000; // time in ms

const submitWrapper = async () => {
 const res = await handleSubmit();
 setTimeout(submitHandler, delay);
} 


setTimeout(submitHandler, delay);

Note I am only showing how to call the intervall or the timeout. How this fits into your initial call or into your app is something else to be discussed. Feel free to ask a little more specific questions for further support.

1

You don’t have to fetch in the background every second(s) just to check if access token is still valid. Let the user/client trigger the action for you.

Scenario:

  1. the logged in user send a request (e.g. by refreshing the page, navigating
    to other route
    ).
  2. server say recieved accessToken expired.
  3. client recieve the message that accessToken expired.
  4. therefore client request a new accessToken by sending refreshToken to your /refresh-token endpoint.
  5. server verify that sent refreshToken still valid.
  6. server generate a new accessToken and send it to client.

1

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật