What you will learn

This lab teaches you to observe a sign-in session without exposing its credential. You will connect explicit login, session-check and logout buttons to documented Gammal Tech methods, then record what the interface does. The page reports session-related state only; it does not establish application permissions or prove that a customer has paid.

Start with a ready, authorized practice project

Complete the first-project exercise before this lab: use your verified individual account, an authorized registered HTTPS domain and the official SDK loaded once before your application script. The examples below belong inside that practice page. They depend on the documented GammalTech global being available.

Use no customer records, payment flow or paid entitlement in this exercise. If another learner participates, each person uses their own account without sharing credentials. Your deliverable is a session behavior record, the page source and safe screenshots showing status messages. None should contain a session token.

Read the official SDK method descriptions before running the exercise. Keep the implementation small enough that you can explain every event handler.

Distinguish three different observations

SDK readiness means a library and its methods loaded. Sign-in state is the state the SDK reports for the current browser tab. Authorization is the decision that a particular action is allowed. These observations are related, but none should silently stand in for another.

The documented helpers include isLoggedIn(), onAuth(onIn, onOut) and verify(). The published SDK guide does not define a resolved payload schema for verify(), so this exercise does not read invented fields such as result.valid. After an action, it refreshes the displayed SDK state. It never treats promise resolution alone as permission to access a record or release a purchase.

OWASP's session guidance explains the sensitivity of a session credential. You can learn the flow without printing that credential or adding it to a URL.

Add three explicit controls

Add this markup in the page body before your application script. The buttons have visible names, and status text can be announced by assistive technology. There is no automatic login on page load.

<p id="auth-state" role="status" aria-live="polite">
  Checking sign-in state…
</p>
<p id="action-message" role="status" aria-live="polite"></p>
<button id="sign-in" type="button">Sign in</button>
<button id="check-session" type="button">Check session</button>
<button id="sign-out" type="button">Sign out</button>

A single clear interface makes the exercise observable. The sign-in button starts the login process after a deliberate user click. The session-check button is a separate action, so you can distinguish it from opening the page. The sign-out button gives you a repeatable way to observe a change in the current session.

Keep credentials out of the interface

Place the next block in your application script after the markup and SDK load. It prevents overlapping button actions during this small exercise, renders text safely and uses a fixed message if an operation fails.

const state = document.getElementById("auth-state");
const message = document.getElementById("action-message");
const buttons = ["sign-in", "check-session", "sign-out"]
  .map(id => document.getElementById(id));
let busy = false;
function render() {
  state.textContent = GammalTech.isLoggedIn()
    ? "SDK reports signed in for this tab."
    : "SDK reports signed out for this tab.";
}
async function perform(task) {
  if (busy) return;
  busy = true;
  buttons.forEach(button => { button.disabled = true; });
  message.textContent = "Working…";
  try {
    await task();
    render();
    message.textContent = "Action completed. Read the tab state.";
  } catch {
    message.textContent = "Unable to finish. Please try again later.";
  } finally {
    busy = false;
    buttons.forEach(button => { button.disabled = false; });
  }
}
render();

Now add the event wiring immediately below that block:

buttons[0].addEventListener("click", () =>
  perform(() => GammalTech.login()));
buttons[1].addEventListener("click", () =>
  perform(() => GammalTech.verify()));
buttons[2].addEventListener("click", () =>
  perform(() => GammalTech.logout()));
GammalTech.onAuth(render, render).catch(() => {
  message.textContent = "Sign-in state is unavailable. Try again later.";
});

The call to login() occurs directly from the click handler through perform. Its returned token is deliberately unused. No exception detail is printed. The buttons becoming disabled is a user-interface convenience, not an authorization control. The SDK has its own network retry behavior; do not add a loop that repeatedly invokes login or other actions.

Run the acceptance cases and record actual behavior

Acceptance cases for the session learning page
CaseExpected observationEvidence to keep
Open the pageStatus appears without a forced login popupSafe initial screenshot
Click Sign in and complete the flowThe interface refreshes the reported tab stateState text, without credentials
Click Check sessionThe documented method runs; the UI does not invent a verification payloadObserved action and state
Click Sign outThe UI reflects the resulting signed-out stateState text after completion
Cancel login or encounter a failureNo exception or token is exposed; controls remain usableObserved behavior and a note

Record what happened, including whether cancellation rejects or leaves the state unchanged. The guide does not specify every cancellation representation, so do not write an expected error string that the SDK never promised. For a check you did not run, write “not tested.”

Investigate one common misunderstanding

The documentation describes a tab-based session and a new login for a fresh or reopened tab. Try that behavior in your authorized environment and record each tab separately. Do not infer that closing a tab revokes every session, erases every browser trace or signs the person out on every device.

A common mistake is adding getToken() output to a debug label because the login state seems unclear. Avoid that shortcut. The exercise needs a state description, not the credential carrying the session. Screenshots and copied network records can travel far beyond the original learning environment.

If the displayed state appears stale after a failure, describe that limitation in the test record and rerun a documented state check. A status label is an observation, not independent proof that a remote session is valid. Do not reuse this demo label as a production access gate.

Finish with a boundary statement and your next test

Write a short boundary statement: “This page demonstrates documented session methods and status handling. It does not decide who may administer the application, change a price or receive a paid product.” Add a sentence explaining why a hidden button or editable preference cannot make those decisions trustworthy.

OWASP's authorization guidance treats permission checks as a separate responsibility. In the next data exercise, use an ordinary preference that the learner is allowed to change. Keep authoritative roles, payment status and fulfillment decisions out of that record.

Your completed record should identify the domain, exercise version, cases run, outcomes and unresolved questions. This gives another person enough information to review your learning without seeing any private account material.

Common questions

Why not display the token to prove login worked?

A token is sensitive session material, not a demonstration badge. Use the documented state helpers and record visible behavior without exposing the credential.

Does verify() let the frontend authorize a paid feature?

A session check and a paid entitlement answer different questions. This lab does not interpret an undocumented verify payload or use browser state as trusted payment or authorization evidence.

Lesson references

Documentation checked on 12 October 2026. Recheck current documentation before implementing or quoting a client project.

Start your Gammal Tech exercise

Read the lesson, then practise with fictional data on a site you own or are authorized to use. Use your own verified individual account and open Developer Mode to configure your project. While awaiting verification, start with the data map and test plan.

Back to Articles & Guides