DEV Community

Mohammad Waseem
Mohammad Waseem

Posted on

Automating Authentication Flows with JavaScript on a Zero-Budget Project

Automating Authentication Flows with JavaScript on a Zero-Budget Project

In many startups and small teams, resources are limited, yet the need for secure, scalable authentication mechanisms remains critical. As a senior architect, I faced a challenge: how to streamline and automate auth flows using only free, open-source tools and JavaScript without incurring additional costs.

The Challenge

The goal was to create an automated system that handles user registration, login, token refresh, and session management — all without third-party paid services. The constraints forced us to rely solely on open standards and clever scripting to achieve the desired security and usability.

Strategy and Approach

The solution centers around leveraging OAuth 2.0 and OpenID Connect standards, which are open and widely supported. We also utilize JSON Web Tokens (JWT) for stateless session management, plus open-source libraries for more straightforward implementation.

1. Setting Up a Self-Hosted Authorization Server

Instead of using third-party providers, we deploy a free, open-source identity provider using Keycloak, which is open-source and free. It runs on a local or cloud VM and manages user identities, client apps, and tokens.

# Minimal setup using Docker
docker run -d --name keycloak -p 8080:8080 -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin quay.io/keycloak/keycloak:latest -b 0.0.0.0
Enter fullscreen mode Exit fullscreen mode

Configuring client apps and user flows is done via the Keycloak admin console, making it straightforward to define redirect URIs, roles, and protocols.

2. Implementing the Client-Side Authentication Flow

Using vanilla JavaScript, we implement the Authorization Code flow, which is recommended for web apps.

Login Redirect:

function redirectToLogin() {
  const authUrl = `http://localhost:8080/realms/myrealm/protocol/openid-connect/auth?client_id=myapp&redirect_uri=${encodeURIComponent(window.location.origin + '/callback')}&response_type=code&scope=openid`;
  window.location.href = authUrl;
}
Enter fullscreen mode Exit fullscreen mode

Handling the Callback:

async function handleAuthCallback() {
  const params = new URLSearchParams(window.location.search);
  const code = params.get('code');
  if (code) {
    const tokenResponse = await fetch('http://localhost:8080/realms/myrealm/protocol/openid-connect/token', {
      method: 'POST',
      headers: {'Content-Type': 'application/x-www-form-urlencoded'},
      body: new URLSearchParams({
        grant_type: 'authorization_code',
        code: code,
        redirect_uri: window.location.origin + '/callback',
        client_id: 'myapp'
      })
    });
    const tokens = await tokenResponse.json();
    localStorage.setItem('access_token', tokens.access_token);
    localStorage.setItem('id_token', tokens.id_token);
  }
}
Enter fullscreen mode Exit fullscreen mode

3. Automating Token Refresh

Tokens have limited lifespan, but refresh tokens enable seamless session continuation.

async function refreshToken() {
  const refreshToken = localStorage.getItem('refresh_token');
  if (!refreshToken) return;

  const response = await fetch('http://localhost:8080/realms/myrealm/protocol/openid-connect/token', {
    method: 'POST',
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    body: new URLSearchParams({
      grant_type: 'refresh_token',
      refresh_token: refreshToken,
      client_id: 'myapp'
    })
  });
  const tokens = await response.json();
  localStorage.setItem('access_token', tokens.access_token);
  localStorage.setItem('id_token', tokens.id_token);
}

// Set a timer to refresh tokens periodically
setInterval(refreshToken, 600000); // refresh every 10 minutes
Enter fullscreen mode Exit fullscreen mode

4. Securing API Calls

All resource requests include the access token:

async function fetchProtectedResource() {
  const token = localStorage.getItem('access_token');
  const response = await fetch('/api/data', {
    headers: {
      'Authorization': 'Bearer ' + token
    }
  });
  return response.json();
}
Enter fullscreen mode Exit fullscreen mode

Key Takeaways

  • Leverage open-source tools: Self-hosted OAuth providers like Keycloak eliminate recurring costs.
  • Use standard protocols: OAuth 2.0 and OpenID Connect ensure security and compatibility.
  • Pure JavaScript implementation: Script the flow with minimal dependencies.
  • Automate token lifecycle: Set refresh intervals to keep user sessions alive.

This approach demonstrates how to orchestrate secure, automated auth flows without a budget by combining open standards and free tools, empowering small teams to build professional-grade identity solutions.

References


🛠️ QA Tip

I rely on TempoMail USA to keep my test environments clean.

Top comments (0)