> ## Content Index
> Fetch the complete content index at: https://blog.fabrixly.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# How to Use Refresh Tokens in Fabrixly-IDS
- URL: https://blog.fabrixly.com/how-to-use-refresh-tokens/
- Published: 2026-07-07T03:08:39.000Z
- Updated: 2026-07-10T07:22:42.000Z
- Author: Fabrixly
- Tags: Documentation

## Overview

Refresh tokens let users stay logged in without re‑entering credentials! When an access token expires, use a refresh token to get a new access token (and a new refresh token)!

## Step 1: Enable Refresh Tokens for Your Client

First, make sure your client is configured for refresh tokens:

### Admin Console Setup

1. Go to **Fabrixly-IDS Admin Console** → **Clients** → select your client
2. Under **OAuth/OIDC Settings**:
  - **Grant Types**: add `refresh_token`
  - **Response Types**: add `code` (for authorization code flow)
  - **Scope**: make sure to request `offline_access` in your auth requests!
3. Save!

### API Setup

### Authenticating API Requests

Management API endpoints (like `/api/clients`, `/api/users`, etc.) require administrative authentication. To call them:

1. **Include the Token in the Authorization Header**: Add `-H "Authorization: Bearer <your-admin-jwt-token>"` to your API calls.

**Obtain an Admin JWT Token**:

```bash
curl -X POST https://ids.fabrixly.com/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "admin@example.com",
    "password": "your-admin-password"
  }'

```

*Note: This returns a JSON response containing a `token`.*

```bash
curl -X POST https://ids.fabrixly.com/api/clients \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <your-admin-jwt-token>" \
  -d '{
    "client_name": "Refresh Token App",
    "redirect_uris": ["http://localhost:3011/callback"],
    "response_types": ["code"],
    "grant_types": ["authorization_code", "refresh_token"],
    "token_endpoint_auth_method": "client_secret_basic",
    "auth_mode": "flexible"
  }'

```

## Step 2: Get Refresh Token

To get a refresh token, include `offline_access` in your scope when requesting authorization:

```javascript
const authUrl = client.authorizationUrl({
  scope: 'openid profile email offline_access', // <-- offline_access is key!
  state: 'your-state',
  nonce: 'your-nonce'
});

```

The token response will include `refresh_token`:

```json
{
  "access_token": "ey...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "some-refresh-token-string",
  "id_token": "ey...",
  "scope": "openid profile email offline_access"
}

```

## Step 3: Use Refresh Token to Get New Access Token

When your access token expires, send the refresh token to the token endpoint:

### Example: Using curl

```bash
curl -X POST https://ids.fabrixly.com/oidc/token \
  -u "your-client-id:your-client-secret" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=refresh_token&refresh_token=your-refresh-token"

```

Response includes new access token and new refresh token!

```json
{
  "access_token": "new-access-token...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "new-refresh-token..." // <-- always replace with new one!
}

```

### Example: Using openid-client

Create `refresh-token-app.js`:

```javascript
const express = require('express');
const session = require('express-session');
const { Issuer, generators } = require('openid-client');

const app = express();
const PORT = 3011;

app.use(session({
  secret: 'refresh-tokens-are-convenient',
  resave: false,
  saveUninitialized: true
}));

async function initClient() {
  const issuer = await Issuer.discover('https://ids.fabrixly.com/oidc');
  return new issuer.Client({
    client_id: 'your-refresh-client-id',
    client_secret: 'your-refresh-client-secret',
    redirect_uris: ['http://localhost:3011/callback']
  });
}

let client;
initClient().then(c => client = c);

// Middleware to auto-refresh expired tokens
app.use(async (req, res, next) => {
  if (req.session.tokenSet && req.session.tokenSet.expired()) {
    try {
      console.log('Refreshing token...');
      const newTokenSet = await client.refresh(req.session.tokenSet.refresh_token);
      req.session.tokenSet = newTokenSet;
    } catch (err) {
      console.error('Error refreshing token:', err);
      req.session.destroy();
    }
  }
  next();
});

app.get('/', (req, res) => {
  if (req.session.user) {
    res.redirect('/dashboard');
  } else {
    res.send('<a href="/login">Login</a>');
  }
});

app.get('/login', (req, res) => {
  req.session.state = generators.state();
  req.session.nonce = generators.nonce();
  const authUrl = client.authorizationUrl({
    scope: 'openid profile email offline_access', // Include offline_access!
    state: req.session.state,
    nonce: req.session.nonce
  });
  res.redirect(authUrl);
});

app.get('/callback', async (req, res) => {
  const params = client.callbackParams(req);
  const tokenSet = await client.callback(
    'http://localhost:3011/callback',
    params,
    { state: req.session.state, nonce: req.session.nonce }
  );
  req.session.tokenSet = tokenSet;
  req.session.user = await client.userinfo(tokenSet.access_token);
  res.redirect('/dashboard');
});

app.get('/dashboard', (req, res) => {
  if (!req.session.user) return res.redirect('/');
  
  const token = req.session.tokenSet;
  res.send(`
    <h1>Refresh Token Example</h1>
    <p>Hello, ${req.session.user.email}!</p>
    <p>Access token expires in: ${token.expires_in} seconds</p>
    <p>Token expired? ${token.expired() ? 'Yes' : 'No'}</p>
    <a href="/">Home</a>
  `);
});

app.listen(PORT, () => console.log(`Refresh token app running on http://localhost:${PORT}`));

```

## Refresh Token Rotation

Fabrixly-IDS automatically rotates refresh tokens! Every time you use a refresh token, you get a new one—always use the new refresh token for next time!

## Refresh Token Expiry

Refresh tokens expire after a longer period of time! Configure via `.env` file:

```env
REFRESH_TOKEN_EXPIRY_DAYS=7  # Refresh tokens expire after 7 days

```

## Revoke Refresh Tokens

To revoke a refresh token (log user out of all devices), call the revocation endpoint:

```bash
curl -X POST https://ids.fabrixly.com/oidc/token/revocation \
  -u "your-client-id:your-client-secret" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "token=your-refresh-token&token_type_hint=refresh_token"

```

## Security Best Practices

1. **Store Refresh Tokens Securely**: Never store them in localStorage or frontend code!
2. **Always Use HTTPS**: Never send refresh tokens over unencrypted connections!
3. **Rotate Refresh Tokens**: Fabrixly-IDS does this by default!
4. **Short Expiry**: Use short-lived access tokens and longer-lived refresh tokens!
5. **Revoke When Not Needed**: Revoke refresh tokens when user logs out!

## Troubleshooting

- **"No refresh token in response"**: Make sure you included `offline_access` in your scope!
- **"Invalid refresh token"**: Make sure you're using the latest refresh token (they rotate)!
- **"Refresh token expired"**: User needs to re-authenticate!

## Next Steps

- Implement token revocation on logout!
- Set appropriate expiry times for tokens!