Captive Portal Authentication Methods: Email, SMS, and Social Login

Captive portals offer multiple ways for users to authenticate before accessing WiFi. Each method has different trade-offs in terms of user experience, data collection, security, and implementation complexity. Understanding these options helps administrators choose the right authentication strategy for their venue.

Overview of Authentication Methods

Method User Experience Data Collected Security Implementation Complexity
Email Simple (enter email) Email address Medium (no verification) Low
SMS Medium (enter phone + code) Phone number, verification High (2FA) Medium
Social (Facebook/Google) Fast (one-click) Name, email, location, interests High (OAuth 2.0) Medium
Password/Voucher Medium (type code) None (pre-generated) High (secret known only to user) Low
None (Open) Instant (no login) None Low (anyone can connect) Very Low

Method 1: Email Authentication

How It Works

  1. User enters email on captive portal login page

  2. Portal validates email format (regex check: ^[a-zA-Z0-9._+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$)

  3. Portal checks database for existing email

  4. If new: INSERT new user record

  5. If existing: Update last login timestamp

  6. Create session with user ID + MAC + IP + expiration

  7. Update firewall ACL to grant internet access

Database Schema

sql
CREATE TABLE users (
user_id INT PRIMARY KEY AUTO_INCREMENT,
email VARCHAR(100) UNIQUE NOT NULL,
mac_address VARCHAR(17),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_login TIMESTAMP
);

CREATE TABLE sessions (
session_id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT,
mac_address VARCHAR(17),
ip_address VARCHAR(15),
start_time TIMESTAMP,
expiration TIMESTAMP,
status ENUM('active', 'expired')
);

User Experience

text
┌─────────────────────────────────┐
│ Welcome to CafeWiFi │
│ │
│ Enter your email to connect: │
│ ┌──────────────────────────┐ │
│ │ john@email.com │ │
│ └──────────────────────────┘ │
│ │
│ [Connect Button] │
│ │
│ Or login with: │
│ [Facebook] [Google] │
└─────────────────────────────────┘

Steps:

  1. User opens browser → Sees login page

  2. Types email → Clicks "Connect"

  3. Gets instant access (no email verification)

  4. Pro: Fast, simple

  5. Con: No verification (fake emails possible)

Pros & Cons

Pros Cons
✅ Simple for users (just type email) ❌ No email verification (fake emails possible)
✅ Fast authentication (instant access) ❌ Low security (no 2FA)
✅ Collects email for CRM/marketing ❌ Privacy concerns (some users hesitant)
✅ Low implementation complexity ❌ Email spam risk (users may not want marketing)

Implementation (PHP Example)

php
<?php
// Captive Portal Login Handler
$email = $_POST['email'];

// Validate email format
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo "Invalid email format";
exit;
}

// Check database for existing user
$stmt = $pdo->prepare("SELECT user_id FROM users WHERE email = ?");
$stmt->execute([$email]);
$user = $stmt->fetch();

if (!$user) {
// New user: INSERT into database
$stmt = $pdo->prepare("INSERT INTO users (email, mac_address) VALUES (?, ?)");
$stmt->execute([$email, $_SERVER['MAC_ADDRESS']]);
$user_id = $pdo->lastInsertId();
} else {
// Existing user: Update last_login
$user_id = $user['user_id'];
$stmt = $pdo->prepare("UPDATE users SET last_login = NOW() WHERE user_id = ?");
$stmt->execute([$user_id]);
}

// Create session
$expiration = date('Y-m-d H:i:s', strtotime('+1 hour'));
$stmt = $pdo->prepare("INSERT INTO sessions (user_id, mac_address, ip_address, start_time, expiration) VALUES (?, ?, ?, NOW(), ?)");
$stmt->execute([$user_id, $_SERVER['MAC_ADDRESS'], $_SERVER['IP_ADDRESS'], $expiration]);

// Grant internet access
grant_internet_access($_SERVER['MAC_ADDRESS']);

echo "Login successful! You have 1 hour of access.";
?>

Best Use Cases

  • Cafes & coffee shops: Collect emails for newsletters

  • Retail stores: Build customer database for marketing

  • Small venues: Simple setup, no complex integration needed


Method 2: SMS Authentication

How It Works

  1. User enters phone number on captive portal

  2. Portal generates 6-digit code (random: 123456)

  3. Portal sends SMS via API (e.g., Twilio, AWS SNS)

  4. User receives SMS on phone

  5. User enters code on portal

  6. Portal validates code against database

  7. If valid: Create session → Grant access

  8. If invalid: Show error → Retry

Database Schema

sql
CREATE TABLE sms_verifications (
verification_id INT PRIMARY KEY AUTO_INCREMENT,
phone_number VARCHAR(15) NOT NULL,
code VARCHAR(6) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
expires_at TIMESTAMP,
verified BOOLEAN DEFAULT FALSE
);

User Experience

text
┌─────────────────────────────────┐
│ Welcome to CafeWiFi │
│ │
│ Enter your phone number: │
│ ┌──────────────────────────┐ │
│ │ +254712345678 │ │
│ └──────────────────────────┘ │
│ │
│ [Send Code Button] │
│ │
│ ─────────────────────────────── │
│ │
│ Enter the code you received: │
│ ┌──────────────────────────┐ │
│ │ 123456 │ │
│ └──────────────────────────┘ │
│ │
│ [Verify Button] │
└─────────────────────────────────┘

Steps:

  1. User types phone → Clicks "Send Code"

  2. Gets SMS: "Your CafeWiFi code is 123456"

  3. Enters code → Clicks "Verify"

  4. Gets instant access

  5. Pro: High security (2FA)

  6. Con: Slower (waiting for SMS)

SMS Flow Diagram

text
User Device → Captive Portal → Enter Phone → POST /send-code
Captive Portal → SMS API (Twilio) → POST phone + code
SMS API → Mobile Network → User Phone receives SMS
User Phone → User reads code → Enters on portal → POST /verify
Captive Portal → Database Check → Code valid? → YES
Captive Portal → Create Session → Grant internet access

SMS API Integration (Twilio Example)

python
from twilio.rest import Client

# Twilio credentials
client = Client("AC1234567890abcdef1234567890abcdef", "your_auth_token")

def send_verification_code(phone_number):
# Generate 6-digit code
code = str(random.randint(100000, 999999))

# Store code in database (expires in 5 minutes)
expires_at = datetime.now() + timedelta(minutes=5)
db.insert("sms_verifications", phone_number=phone_number, code=code, expires_at=expires_at)

# Send SMS via Twilio
message = client.messages.create(
body=f"Your CafeWiFi code is {code}",
from_="+1234567890", # Twilio number
to=phone_number
)

return message.sid

Verification Handler (Python Example)

python
def verify_code(phone_number, code):
# Check database for verification record
record = db.query("SELECT * FROM sms_verifications WHERE phone_number = ? AND code = ?", phone_number, code)

if not record:
return False, "Invalid code"

if record.expires_at < datetime.now():
return False, "Code expired"

if record.verified:
return False, "Code already used"

# Mark as verified
db.update("sms_verifications", verification_id=record.id, verified=True)

# Create session and grant access
create_session(phone_number=phone_number)
grant_internet_access(mac_address)

return True, "Success"

Pros & Cons

Pros Cons
✅ High security (2FA verification) ❌ Slower user experience (waiting for SMS)
✅ Phone number verified (real user) ❌ SMS delivery issues (network problems)
✅ Collects phone for marketing campaigns ❌ SMS cost (Twilio: $0.0075 per SMS in Kenya)
✅ Reduces fake accounts ❌ Privacy concerns (some users don't want SMS)

Best Use Cases

  • High-security venues: Airports, corporate offices

  • Payment-based WiFi: Verify phone before charging

  • Marketing campaigns: SMS promotions to verified users


Method 3: Social Login (Facebook, Google, LinkedIn)

How It Works (OAuth 2.0)

  1. User clicks "Login with Facebook" on captive portal

  2. Portal redirects to Facebook OAuth (https://www.facebook.com/dialog/oauth)

  3. User authenticates with Facebook (if not already logged in)

  4. Facebook returns access token to portal (?access_token=abc123)

  5. Portal exchanges token for user data via Facebook API

  6. Facebook API returns: Name, email, location, profile picture, interests

  7. Portal stores data in database

  8. Create session → Grant internet access

OAuth 2.0 Flow Diagram

text
User Device → Captive Portal → Click "Login with Facebook"
Captive Portal → Redirect to Facebook OAuth → https://facebook.com/dialog/oauth?client_id=...
Facebook → User logs in (if needed) → Ask permission: "Allow CafeWiFi to access your name, email, location?"
User → Click "Allow" → Facebook redirects back to portal
Facebook →Portal → ?access_token=abc123
Portal → Exchange token for user data → Facebook API GET /user?access_token=abc123
Facebook API → Returns: {name: "John Doe", email: "john@email.com", location: "Nairobi", picture: "..."}
Portal → Store in database → Create session → Grant internet access

Database Schema

sql
CREATE TABLE social_users (
user_id INT PRIMARY KEY AUTO_INCREMENT,
social_provider VARCHAR(20) NOT NULL, -- 'facebook', 'google', 'linkedin'
social_id VARCHAR(50) UNIQUE NOT NULL, -- Facebook user ID
name VARCHAR(100),
email VARCHAR(100),
location VARCHAR(100),
profile_picture VARCHAR(200),
interests TEXT, -- JSON array: ["travel", "food", "technology"]
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

User Experience

text
┌─────────────────────────────────┐
│ Welcome to CafeWiFi │
│ │
│ Login to connect: │
│ │
│ [Login with Email] │
│ │
│ Or use social: │
│ [Facebook Logo] Login with Facebook │
│ [Google Logo] Login with Google │
│ [LinkedIn Logo] Login with LinkedIn │
│ │
│ By logging in, you agree to │
│ our Terms & Conditions. │
└─────────────────────────────────┘

Steps:

  1. User clicks "Login with Facebook"

  2. Redirects to Facebook → Authorizes access

  3. Returns to portal with data

  4. Gets instant access (no typing)

  5. Pro: Fastest (one-click)

  6. Con: Privacy concerns (some users don't want social login)

Facebook OAuth Integration (Python Example)

python
import requests

def facebook_login(access_token):
# Exchange token for user data
url = "https://graph.facebook.com/v18.0/me"
params = {
"fields": "id,name,email,location,picture,interests",
"access_token": access_token
}

response = requests.get(url, params=params)
user_data = response.json()

# Extract data
social_id = user_data['id']
name = user_data['name']
email = user_data['email']
location = user_data['location']['name']
picture = user_data['picture']['data']['url']
interests = user_data.get('interests', [])

# Store in database
db.insert("social_users",
social_provider="facebook",
social_id=social_id,
name=name,
email=email,
location=location,
profile_picture=picture,
interests=json.dumps(interests))

# Create session
create_session(user_id)
return True

Google OAuth Integration (Python Example)

python
def google_login(access_token):
# Exchange token for user data
url = "https://www.googleapis.com/oauth2/v2/userinfo"
headers = {"Authorization": f"Bearer {access_token}"}

response = requests.get(url, headers=headers)
user_data = response.json()

# Extract data
social_id = user_data['id']
name = user_data['name']
email = user_data['email']
picture = user_data['picture']

# Store in database
db.insert("social_users",
social_provider="google",
social_id=social_id,
name=name,
email=email,
profile_picture=picture)

# Create session
create_session(user_id)
return True

Pros & Cons

Pros Cons
✅ Fastest (one-click authentication) ❌ Privacy concerns (users share data with venue)
✅ Rich data collection (name, email, location, interests) ❌ Requires social media account (not all users have)
✅ High security (OAuth 2.0, Facebook verifies user) ❌ Dependency on third-party (Facebook can change API)
✅ Marketing integration (Facebook Pixel for ad targeting) ❌ Social login may feel intrusive to some users

Data Collection Comparison

Data Type Email SMS Facebook Google
Name ❌ ❌ ✅ ✅
Email ✅ ❌ ✅ ✅
Phone ❌ ✅ ❌ ❌
Location ❌ ❌ ✅ ✅
Profile Picture ❌ ❌ ✅ ✅
Interests ❌ ❌ ✅ ❌
Friends/Followers ❌ ❌ ✅ (partial) ❌

Best Use Cases

  • Marketing-focused venues: Collect rich data for campaigns

  • Cafes & restaurants: Social sharing drives engagement

  • Hotels: Build customer profiles for personalized service

  • Retail stores: Facebook Pixel tracks visitors for ad targeting


Method Comparison Table

Feature Email SMS Social (Facebook) Social (Google) Password/Voucher
User Speed Fast (1 step) Medium (2 steps) Fastest (1-click) Fastest (1-click) Medium (1 step)
Security Low High (2FA) High (OAuth) High (OAuth) High (secret)
Data Collected Email only Phone only Name, email, location, interests Name, email, photo None
Fake Accounts Possible Unlikely Unlikely Unlikely Unlikely
Cost $0 $0.0075/SMS $0 $0 $0
Implementation Low Medium Medium Medium Low
Best For CRM building Verification Marketing Marketing Paid WiFi

Choosing the Right Method

For Marketing & CRM

  • Best: Social Login (Facebook/Google)

  • Why: Collect rich data (name, email, location, interests) for personalized campaigns

For Security & Verification

  • Best: SMS Authentication

  • Why: 2FA verification ensures real user, reduces fake accounts

For Simplicity & Speed

  • Best: Email Authentication

  • Why: Fastest setup, easiest for users (just type email)

For Paid WiFi

  • Best: Password/Voucher

  • Why: Pre-generated codes, no user data needed, secure

For Maximum Data Collection

  • Best: Social Login (Facebook)

  • Why: Most data points (name, email, location, interests, profile picture, friends)


Multi-Method Authentication

Most modern captive portals support multiple methods simultaneously:

text
┌─────────────────────────────────┐
│ Welcome to CafeWiFi │
│ │
│ Choose your login method: │
│ │
│ [Email Input] [Connect] │
│ │
│ Or use social: │
│ [Facebook] [Google] [LinkedIn] │
│ │
│ Or enter voucher: │
│ [Voucher Code Input] [Verify] │
│ │
│ Terms & Conditions: [✓ I agree] │
└─────────────────────────────────┘

Benefits:

  • Flexibility: Users choose their preferred method

  • Data diversity: Collect emails, phones, and social profiles

  • Higher conversions: More options = more users authenticate


Bottom Line

Captive portal authentication offers email, SMS, and social login as the three primary methods. Email is simplest but has low security. SMS provides high security with 2FA but is slower. Social login (Facebook/Google) is fastest and collects the most data but raises privacy concerns.

Choose based on your goals:

  • Marketing: Social Login (rich data)

  • Security: SMS (2FA verification)

  • Simplicity: Email (fast setup)

  • Paid WiFi: Voucher (pre-generated codes)

Most venues use multi-method authentication to offer flexibility and maximize conversions.

Scroll to Top