How does WeWeb handle the Refresh Token process?

Hi there,

I’ve implemented a token based auth login and do receive a refresh token from my database. In the plugin, I’ve added the refresh token endpoint as well:

In the login workflow, I used the “Store Token” and “Fetch User” action from WeWeb:

My question:
Is there already some magic happening in the background of that plugin that automatically uses the refresh endpoint + refresh token in case the access_token has expired?

If not, can anyone let me know where to create a global workflow that works on all pages in case the access_token has expired?

It looks like a lot has changed since this 2 year old video: https://www.youtube.com/watch?v=ZB3NbK4t5b4

Solved with the following approach:

  1. Built a global workflow which fires on every local workflow, that needs to make an authorized API request.

  2. The global workflow checks via Javascript, if the accessToken is still valid. Grab from variable.
    I used this JS to grab the variables and calculate expiry:

// Retrieve the stored access token
let token = wwLib.wwVariable.getValue("accessToken");

// Check if token exists before trying to modify it
if (!token) {
    console.error("No access token found. Token is null or undefined.");
    return "invalid";
}

// Ensure it's a string before using `.replace()`
if (typeof token !== "string") {
    console.error("Token is not a string:", token);
    return "invalid";
}

// Remove any extra quotes
token = token.replace(/"/g, "");

// Function to decode JWT
function decodeJwt(token) {
    try {
        const base64Url = token.split(".")[1]; // Extract payload
        const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
        return JSON.parse(atob(base64));
    } catch (e) {
        console.error("Invalid JWT format");
        return null;
    }
}

// Decode token and check expiry
const decodedToken = decodeJwt(token);
console.log("Decoded Token:", decodedToken);

if (!decodedToken || !decodedToken.exp) {
    console.error("Token decoding failed or missing expiry.");
    return "invalid";
}

// Check if token is expired
const currentTime = Math.floor(Date.now() / 1000);
const isExpired = decodedToken.exp <= currentTime;
console.log("Token Expired:", isExpired);

return isExpired ? "expired" : "valid";
  1. If valid, continue.
    If expired, grab refreshToken from httpOnly Cookie and check if valid (expires much later, s. table below). These Refresh Token should never be stored in variables, because they can get stolen and hackers could refresh the access token continuously. Better: Store in sessionStorage or httpOnly Cookie.

  2. If refreshToken is still valid, make an API request to get a new accessToken.
    If refreshToken is expired, redirect to login page.


In my case, I am using Directus for user authenticiation. But here is how other WeWeb favorites handle it:

Platform Access Token Expiry Refresh Token Expiry Auto-Refresh?
Directus 15 min 7 days :x: Needs manual /auth/refresh
Xano 1 hour (default, configurable) Optional :x: Requires re-authentication
Supabase 1 hour Up to 1 month :white_check_mark: Auto-refresh with refreshSession()
3 Likes