DEV Community

Saif Jlassi
Saif Jlassi

Posted on

Building a Secure Multi-Device Authentication System: The SyncBridge Story #1🔐

Ever wondered how apps like WhatsApp Web handle secure device pairing? Or how Netflix manages to keep track of all your devices? Today, I'm diving deep into how I built SyncBridge's authentication system, handling everything from QR code login to token refresh mechanisms. Buckle up - it's gonna be a fun ride! 🚀

The Challenge 🎯

Building SyncBridge's auth system wasn't just about letting users log in. I needed to:

  • Track multiple devices per user
  • Handle secure device pairing
  • Manage token refresh without compromising security
  • Implement email verification
  • Monitor suspicious activities

The Architecture 🏗️

Here's what I came up with:

Image description

The Secret Sauce 🌟

What makes this system special? Three key ingredients:

  1. Device-Specific Tokens: Each device gets its own unique identifier and refresh token. If one device is compromised, others stay safe.

  2. Rotating Refresh Tokens: Every time a refresh token is used, it's invalidated and a new one is issued. This means if someone steals your refresh token, they have exactly one shot at using it.

  3. Security Event Tracking: Every login, token refresh, and device pairing is monitored. Suspicious patterns? We catch them before they become problems.

Let's Get Technical 🛠️

Token Management: The Dance of Access and Refresh 💃

Remember the last time you stayed logged into an app for weeks without entering your password? That's the magic of refresh tokens. But here's how we made it more secure in SyncBridge:

The Two-Token Tango 🎭

Image description

Why This Matters 🤔

Here's what makes our token system special:

  1. Single-Use Refresh Tokens
// When refreshing tokens
const deviceAuth = this.deviceAuthRepository.create({
device_id: device.device_id,
refresh_token: refreshToken,
expires_at: new Date(Date.now() + 7 24 60 60 1000), // 7 days
is_valid: true,
});
Enter fullscreen mode Exit fullscreen mode
  1. Device-Bound Tokens
    Each refresh token is tied to a specific device. Try using it from another device? Not happening! 🚫

  2. Concurrent Request Handling

if (isRefreshing) {
try {
const token = await new Promise((resolve, reject) => {
failedQueue.push({ resolve, reject });
});
// Handle concurrent requests during refresh
}
}
Enter fullscreen mode Exit fullscreen mode

The Security Checklist ✅

  • ✅ Access tokens expire in 15 minutes
  • ✅ Refresh tokens are single-use
  • ✅ Device fingerprinting for extra security
  • ✅ Token rotation on every refresh
  • ✅ Concurrent request queue management

QR Code Magic: Secure Device Pairing 📱

One of the coolest features we built is the QR code login system. You know when you open WhatsApp Web and scan that QR code? We built something similar, but with our own security twist!

How It Works 🔍

Image description

When you click "Add Device", here's what happens behind the scenes:

async generateLoginQR(userId: string): Promise<{ qrId: string; qrCode:string }> {
// Generate unique QR session ID
const qrId = uuidv4();
// Store QR session with Redis (5 minutes expiration)
await this.redis.set(
qr_login:${qrId},
JSON.stringify({
status: 'pending',
ownerId: userId,
createdAt: new Date().toISOString(),
}),
'EX',300
);
Enter fullscreen mode Exit fullscreen mode

Security First! 🛡️

Here's how we keep the QR login secure:

  1. Time-Limited Sessions: Each QR code expires in 5 minutes
  2. One-Time Use: Once scanned, the QR code becomes invalid
  3. Device Verification: We check if the scanning device is authorized
  4. Real-time Status Updates: Using Redis for instant status changes

Image description

The User Experience 🎯

  1. User opens SyncBridge on their computer
  2. Clicks "Add Device" and gets a unique QR code
  3. Scans with their phone (already logged in)
  4. Both devices get notified of successful pairing
  5. New device receives its own unique tokens
// Real-time QR status monitoring
const checkQRStatus = async (qrId: string) => {
const status = await redis.get(qr_login:${qrId});
if (status.authenticated) {
// Handle successful authentication
const { deviceId, tokens } = status;
await setupNewDevice(deviceId, tokens);
}
};
Enter fullscreen mode Exit fullscreen mode

Email Verification: Double-Check Everything ✉️

Every new device pairing triggers an email notification:

Image description

This gives users instant visibility into their account activity and a chance to revoke access if something looks suspicious.

Security Monitoring: The Guardian Angel 👀

What happens after users log in? We keep watching! Here's our security monitoring system in action:

Event Tracking System 📊

async logSecurityEvent(params: {
user: User,
device: Device,
event_type: SecurityEventType,
severity: SecurityEventSeverity,
}) {
// Log and monitor security events
}
Enter fullscreen mode Exit fullscreen mode

What We Track 🔍

  • 🚪 Login attempts (successful and failed)
  • 🔄 Token refresh patterns
  • 📱 Device pairing activities
  • 🌍 Geographic anomalies
  • ⚠️ Suspicious IP changes

Putting It All Together 🎯

Here's what makes SyncBridge's authentication special:

  1. Zero Trust Architecture

    • Every request is verified
    • No device is inherently trusted
    • Continuous validation
  2. User-First Security

    • Clear email notifications
    • Device management dashboard
    • One-click device revocation
  3. Future-Proof Design

    • Scalable token management
    • Extensible security events
    • Ready for new auth methods

Final Thoughts 💭

Building a secure authentication system is like building a house - you need a solid foundation (token management), good locks (QR code pairing), and a reliable security system (event monitoring).

The best part? This is just the beginning. Next up: implementing biometric authentication and hardware key support! 🚀


Found this helpful? Follow me for more deep dives into web security and full-stack development!
LINKED IN : https://www.linkedin.com/in/seif-eddine-jlassi/
GITHUB REPO :https://github.com/laakri/SyncBridge

Top comments (0)