Understand sign-in

For a web application, the sign-in zone is an iframe on your page. Users stay on your URL while they enter their code and their PIN on the Kie.la authentication server. Your backend finishes the session on your domain.

Try live embed styles

A red dashed outline marks the empty <div> you add in your own page.

How it works

Prepare a welcome iframe on your page.
The user signs in through this iframe, served by the Kie.la authentication server.
Then your code finishes the session on your domain.

HTML and CSS Adapt

Add an empty <div> to host the sign-in iframe. You choose where it sits on your page. The authentication server chooses the iframe size (via a postMessage call).

  1. Place the mount div in the header row and adapt the CSS so there is room for the embed from the authentication server.
  2. Give the header a z-index above the page content (e.g. 1100) so the iframe is not covered.
  3. Set overflow: visible so the mount div is not clipped.
  4. Keep two possible display areas (splash or home). Hide the mount div after sign-in.
<header class="site-header" style="position:fixed; z-index:1100;">
  <h1>My shop</h1>
  <div id="authHeaderRoot" class="header-auth"></div>
</header>

<section id="splash">… public page …</section>
<section id="home" hidden>… signed-in page …</section>

<script src="/lib/kie-la-auth.js"></script>
.header-auth {
  margin-left: auto;
  display: flex;
  align-items: center;
  overflow: visible;
}

Implement two routes Do not change

Your server must expose these two routes before the iframe is loaded.

  1. GET /api/me — says whether a session already exists on your domain. 200 and the profile: the user is signed in, show home. 401: no session, show splash.
  2. GET /api/config — tells the browser the authentication server address (authOrigin) and the profile fields. The response is public: no secret, no uuid.

Load the iframe (KieLaAuth.mount) Do not change

When the public page is shown and the user is not already signed in, the client runs the requests below. The browser calls an API on your server — e.g. /api/me — and gets a status code and JSON (or an error).

  1. Check session — HTTP GET /api/me on your origin.
  2. Read config — HTTP GET /api/config on your origin. Returns authOrigin, among other fields.
  3. Mount — KieLaAuth.mount({ … }). Builds the iframe source with HTTP GET /api/auth/embed?authUi=header&parentOrigin=… for the authentication server.
  4. Resize — the iframe page calls postMessage (browser API) to report the embed width and height; kie-la-auth.js resizes the iframe. NB: do not hard-code the height, or you may clip the div.
// Already implemented in the page client — you do not write or modify this.
fetch("/api/me", { credentials: "include" })
  .then((r) => (r.ok ? r.json() : null))
  .then((data) => {
    if (data?.profile) return showHome(data.profile);
    return fetch("/api/config").then((r) => r.json());
  })
  .then((cfg) => {
    if (!cfg) return;
    authHandle = KieLaAuth.mount({
      minimalIframeRoot: document.getElementById("authHeaderRoot"),
      authUi: "header",
      authOrigin: cfg.authOrigin,
      onSuccess: (session) => showHome(session.profile),
    });
  });

What the user does (inside the iframe) Do not change

The sign-in fields are rendered by the authentication server inside the iframe.

  1. Passcode — The user types the 6-character code read in the Kie.la app on their phone and enters it in the iframe.
  2. PIN — The user then types their PIN.
  3. Submit — After 10 characters, HTTP POST /api/verify on the authentication server.

What happens next Do not change

  1. The authentication server returns an exchange token (one-time, short-lived).
  2. The iframe calls window.parent.postMessage({ exchange, … }). The client page retrieves the token.
  3. The page requests the client server with HTTP POST /api/session and retrieves the exchange token.
  4. The client backend calls the authentication server server-to-server to exchange the exchange token for a session id and the user profile.
    The backend sets a Set-Cookie (HttpOnly session cookie) and the JSON { ok: true, profile }.
  5. Adapt onSuccess from HTTP POST /api/session: the page uses the profile to show the authenticated page.
  6. On the next visit, HTTP GET /api/me retrieves the cookie automatically.

Variant — your own session Adapt

For an application that keeps the session itself. The first two points are the same as step 5.

  1. The authentication server returns an exchange token (one-time, short-lived).
  2. The iframe calls window.parent.postMessage({ exchange, profile, … }). The client page retrieves the token and the profile.
  3. The page does not call HTTP POST /api/session.
  4. Adapt The application stores the profile in its own session (cookie, JWT, or store). No server-to-server exchange, and no Kie.la session cookie.
  5. Adapt The page uses this profile to show the authenticated page.
  6. On the next visit, the application reads its own session.

HTTP and messages — reference

The rest is on the Implement page.