How to Use Hybrid Flow with Fabrixly-IDS

Overview

The Hybrid Flow combines aspects of Authorization Code Flow and Implicit Flow! It returns some tokens immediately from the authorization endpoint and an authorization code that can be exchanged for more tokens! It's useful for apps that want both immediate tokens and refresh tokens!

Step 1: Configure Hybrid Flow Client

First, set up your client for hybrid flow:

Admin Console Setup

  1. Go to Fabrixly-IDS Admin ConsoleClients
  2. Create or edit a client:
    • Response Types: add code, id_token, token (any combination)
    • Grant Types: add authorization_code, implicit, refresh_token
    • Token Endpoint Auth Method: choose client_secret_basic or client_secret_post
    • Auth Mode: choose any auth mode
  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:

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.

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

Step 2: Example Hybrid Flow App

Create hybrid-flow-app.js:

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

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

app.use(session({
  secret: 'hybrid-flow-is-versatile',
  resave: false,
  saveUninitialized: true
}));

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

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

app.get('/', (req, res) => {
  if (req.session.user) {
    res.redirect('/dashboard');
  } else {
    res.send(`
      <h1>Hybrid Flow Example</h1>
      <a href="/login">Login with Hybrid Flow</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',
    response_type: 'code id_token token',
    state: req.session.state,
    nonce: req.session.nonce
  });
  res.redirect(authUrl);
});

app.get('/callback', async (req, res) => {
  // Get params from URL (includes code, id_token, access_token)
  const params = client.callbackParams(req);
  
  // First validate the id_token and access_token from authorization endpoint
  // Then exchange code for refresh_token
  const tokenSet = await client.callback(
    'http://localhost:3010/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('/');
  
  res.send(`
    <h1>Hybrid Flow Dashboard!</h1>
    <p>Welcome, ${req.session.user.email}!</p>
    <p>Got tokens via hybrid flow!</p>
    <a href="/">Home</a>
  `);
});

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

Hybrid Flow Response Types

You can use different combinations of response types:

  • code id_token: returns code and id token immediately
  • code token: returns code and access token immediately
  • code id_token token: returns all three!

When to Use Hybrid Flow

  • Apps that need immediate id token for authentication
  • Apps that also need refresh tokens (via exchanging the authorization code)
  • Legacy apps that were designed for hybrid flow

Security Considerations

  • Use HTTPS always!
  • Validate state and nonce!
  • Keep client secret secure!
  • Use short expiry for tokens returned from authorization endpoint!
  • Prefer Authorization Code Flow with PKCE for most new apps!

Troubleshooting

  • "Missing response_type": Check client's response_types includes the ones you're requesting!
  • "Invalid grant": Ensure code is valid and hasn't been used before!
  • Tokens missing from response: Verify response_type is correctly set!

Next Steps

  • Try Authorization Code Flow with PKCE instead!
  • Explore refresh token usage!

Subscribe to The Fabrixly Blog

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe