🔄 Login Flow Tutorial
Understand how authentication works step-by-step, from button click to authenticated user.
Flow Overview
When a user clicks login, here's what happens behind the scenes:
Step-by-Step Breakdown
Your app calls GammalTech.login() when the user clicks a login button. The SDK opens a popup window pointing to Gammal Tech Passport.
// User clicks login button
document.getElementById('loginBtn').addEventListener('click', async () => {
const token = await GammalTech.login();
// SDK opens popup, waits for result
});
The SDK opens a centered popup window (500x600px) that loads my.gammal.tech/login. The popup URL includes your domain for verification.
If the browser blocks the popup, GammalTech.login() returns null. Always call login() in direct response to a user click (not in async callbacks) to avoid blockers.
// SDK opens popup like this:
const popup = window.open(
`https://my.gammal.tech/login?domain=${encodeURIComponent(location.origin)}`,
'GammalTechLogin',
'width=500,height=600,left=...,top=...'
);
In the popup, the user sees the Gammal Tech Passport login screen. They can:
Existing User
Enters email/phone, receives OTP via email or WhatsApp, verifies and logs in.
New User
Creates a Gammal Tech Passport account (email + WhatsApp verification + real ID).
Every Gammal Tech Passport user has verified their identity. You get real users, not bots or fake accounts.
After successful authentication, Gammal Tech redirects to your registered callback URL with a token. The popup sends this token back to your main window via postMessage.
<!-- This page receives the token from Gammal Tech -->
<script src="https://api.gammal.tech/sdk-web.js"></script>
<script>
// SDK automatically:
// 1. Extracts token from URL
// 2. Sends it to parent window via postMessage
// 3. Closes the popup
// You can also add custom logic:
const urlParams = new URLSearchParams(window.location.search);
const token = urlParams.get('token');
if (token) {
// Token received successfully
console.log('Auth successful');
}
</script>
Your callback URL must be registered at my.gammal.tech. Gammal Tech will only redirect to registered URLs for security.
The SDK receives the token via postMessage, stores it in sessionStorage, and resolves the Promise. Your app now has an authenticated user!
const token = await GammalTech.login();
if (token) {
// Token is now in sessionStorage
console.log(GammalTech.isLoggedIn()); // true
console.log(GammalTech.getToken()); // "eyJ..."
// Get user info
const user = await GammalTech.verify();
console.log(user); // { success: true, user: { id, name, email } }
// Now you can use other SDK features
const userData = await GammalTech.user.get();
const aiResponse = await GammalTech.ai.ask('Hello!');
}
Complete Working Example
Here's a full implementation you can copy and customize:
<!DOCTYPE html>
<html>
<head>
<title>My App</title>
<script src="https://api.gammal.tech/sdk-web.js"></script>
</head>
<body>
<!-- Guest View -->
<div id="guestView">
<h1>Welcome to My App</h1>
<p>Please log in to continue</p>
<button onclick="handleLogin()">Login with Gammal Tech</button>
</div>
<!-- User View (hidden by default) -->
<div id="userView" style="display:none">
<h1>Welcome, <span id="userName"></span>!</h1>
<p>You are now logged in.</p>
<button onclick="handleLogout()">Logout</button>
</div>
<script>
// Check auth state on page load
async function checkAuth() {
if (GammalTech.isLoggedIn()) {
const result = await GammalTech.verify();
if (result.success) {
showUserView(result.user);
} else {
// Token invalid, clear it
GammalTech.logout();
}
}
}
// Handle login button click
async function handleLogin() {
const token = await GammalTech.login();
if (token) {
const result = await GammalTech.verify();
showUserView(result.user);
}
}
// Handle logout
function handleLogout() {
GammalTech.logout();
showGuestView();
}
// UI helpers
function showUserView(user) {
document.getElementById('userName').textContent = user.name;
document.getElementById('guestView').style.display = 'none';
document.getElementById('userView').style.display = 'block';
}
function showGuestView() {
document.getElementById('guestView').style.display = 'block';
document.getElementById('userView').style.display = 'none';
}
// Run on page load
checkAuth();
</script>
</body>
</html>
Troubleshooting
Problem: GammalTech.login() returns null immediately.
Solution: Call login() directly in a click handler, not in a setTimeout or async callback.
Problem: Popup shows "Domain not authorized" error.
Solution: Add your domain at my.gammal.tech. Include both http://localhost:3000 for dev and https://yourdomain.com for production.
Problem: Popup redirects but token doesn't reach your app.
Solution: Ensure callback.html includes the SDK script and is on a whitelisted domain.
Problem: GammalTech.verify() returns { success: false }.
Solution: Call GammalTech.logout() and prompt user to login again.
AI Prompt for Vibe Coding
Login FlowCopy this prompt for help with login flow implementation: