K

Kunal Auth Documentation

Documentation

A plain-English guide on exactly what code to write and where to put it.

01

The Login Trigger

File Location: index.html (Or your main page with the Login button)

👉 Attach this function to your "Login" button. It packages your app's ID and securely redirects the user to the SSO portal.


function login() {
  const CLIENT_ID = "your_client_id";
  const REDIRECT_URI = "your_redirect_uri";

  const url = new URL("https://sso-production-d29b.up.railway.app/oauth/authorize");
  url.searchParams.set("client_id", CLIENT_ID);
  url.searchParams.set("redirect_uri", REDIRECT_URI);
  url.searchParams.set("response_type", "code");
  url.searchParams.set("scope", "openid email profile");
  url.searchParams.set("state", "random_state");

  window.location.href = url.toString();
}
02

The SSO Redirect (Handshake)

Location: Happens entirely on Kunal Auth Servers

You don't need to write code for this part.

The user enters their credentials on our secure server. Once authenticated, we automatically bounce them back to the REDIRECT_URI you provided in Step 1 (e.g., your auth.html page).

We attach a secret code to the URL, making it look like this:
your_redirect_uri?code=abc123XYZ

03

The Token Exchange

File Location: auth.html (Inside a <script> tag)

👉 This is the logic for your callback page. Put your constants right at the top so the function can use them. It extracts the ?code= from the URL and securely exchanges it for the user's data.


const CLIENT_ID = "your_client_id";
const CLIENT_SECRET = "your_client_secret";
const REDIRECT_URI = "your_redirect_uri";

function handleOAuth() {
  const params = new URLSearchParams(window.location.search);
  const code = params.get("code");

  console.log("CODE:", code);

  // If no code exists, or we already processed it, stop here.
  if (!code || sessionStorage.getItem("oauth_done")) return;

  sessionStorage.setItem("oauth_done", "true");

  fetch("https://sso-production-d29b.up.railway.app/token", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      code,
      client_id: CLIENT_ID,
      client_secret: CLIENT_SECRET,
      redirect_uri: REDIRECT_URI,
    }),
  })
    .then((res) => res.json())
    .then((data) => {
      console.log("TOKEN:", data);

      // Extract User Info and save it
      const user = JSON.parse(atob(data.id_token.split(".")[1]));
      localStorage.setItem("user", JSON.stringify(user));

      console.log("Logged in:", user.email);

      // Clean the URL bar so the "?code=" disappears
      window.history.replaceState({}, document.title, "/auth.html");
    })
    .catch(console.error);
}

*Note: In a true production environment, you should move this Step to a backend server so your CLIENT_SECRET is never visible in the browser.

04

Executing The Flow (Recovery Loop)

File Location: auth.html (Right below the handleOAuth function)

👉 Defining the function isn't enough; you must run it. Because some browsers drop the first network request on new user flows, we run a stacked timeout loop. This guarantees the login completes successfully.


// 🔥 RUN MULTIPLE TIMES (THIS FIXES NEW USER FLOW)
handleOAuth();
setTimeout(handleOAuth, 300);
setTimeout(handleOAuth, 800);