How We Built QR Login at BoxHero Using Cloudflare Durable Objects
Designing a secure, real-time login system that doesn’t rely on email.

At BoxHero, we aim to make managing inventory fast and accessible—whether on desktop or mobile. For most users, authentication is straightforward through Google, Apple, or email-based login. However, we identified a significant point of friction in our email-based authentication flow.
Users frequently reported delays in receiving verification codes, with emails sometimes being routed to spam folders or failing to arrive altogether.
To solve this, we built a cross-device QR login flow that connects your desktop browser to your authenticated mobile session (no email required). This system uses Cloudflare Workers, Durable Objects, and WebSockets to deliver a real-time, secure authentication path without adding load to our main backend.
In this post, we’ll walk through the motivation, system design, challenges, and learnings from building and deploying QR Login at scale.
Our Motivation: The Limitations of Email-Based Login
We identified three main issues with email-based login:
- Unreliable delivery: Emails are sometimes delayed or flagged by spam filters. It’s a common user pain point, especially for first-time logins or teams with strict corporate spam filters.
- Cross-device login: Users often need to switch devices mid-task (e.g., viewing inventory on desktop after scanning items on mobile).
- Redundant authentication: If a user is already logged in on mobile, re-authenticating on desktop feels unnecessary.

QR login offered a clean solution: use a mobile session that’s already authenticated to unlock access on another device.
The challenge was architectural: our primary backend is JVM-based and doesn’t support WebSockets, which we needed for real-time message delivery.
Our Goals: Design Principles Behind QR Login
We set out with the following design goals:
⭐ Temporary & scoped: Each QR login session should expire automatically and support only one connection.
⭐ Real-time communication: Use a persistent connection to transmit the login token without polling.
⭐ Low operational overhead: Build the system outside our core backend, with minimal deployment complexity.
How the QR Login Flow Works
From the user’s perspective, QR login offers a faster and more convenient alternative to email-based authentication. It connects a verified mobile session to a desktop login in just a few steps.

Here’s how it works in practice:
- The user visits the BoxHero login page on their desktop browser.
- A QR code appears, representing a temporary login session.The user opens the BoxHero mobile app (already signed in) and scans the QR code.
- The mobile app displays details about the desktop login attempt, such as browser type and country of origin, for the user to confirm.
- Once confirmed, the mobile app sends a secure token to the server.
- The desktop browser uses this token to complete the login process instantly.
By relying on the user’s existing mobile session, QR login removes the need for verification emails while maintaining strong security guarantees.
System Architecture: How QR Login Is Structured
We designed the QR login system around a real-time communication channel between the user's desktop browser and their authenticated mobile app. The goal was to securely transfer a login token between devices without relying on external services like email.
To achieve this, we used Cloudflare Durable Objects as per-session coordinators, with WebSocket support handled by Cloudflare Workers at the edge.

Each QR login session is backed by a unique Durable Object instance that tracks state, validates inputs, and manages the exchange of information. The system operates entirely outside our primary backend stack, allowing us to add real-time capabilities without introducing WebSocket support into our JVM-based application server.

End-to-End Flow: From QR Code to Session Creation
The login sequence consists of four key steps:
1. Desktop Browser Initiates Session via WebSocket
When a user visits the BoxHero login page on desktop, their browser opens a WebSocket connection to our Worker endpoint at:
httpss://qrlogin.boxhero.io/websocket
A new Durable Object is instantiated using a random unique ID. This object becomes the authoritative source for session state and lifecycle.
As part of the initialization, we capture basic metadata about the desktop client:
• Browser user agent
• Operating system
This metadata is used later for verification. The Durable Object generates a QR code (as an SVG image) embedding the session ID, which the browser displays to the user.
2. Mobile App Scans and Validates
When the user scans the QR code using the BoxHero mobile app, the app extracts the session ID and initiates a secure HTTPS request to the corresponding Durable Object instance.
At this point, the mobile app displays metadata associated with the login attempt (such as the browser, operating system, and country of origin), allowing the user to confirm that the request originated from their own desktop.

In parallel, the desktop client shows a confirmation screen that prompts the user to approve the login from their mobile device.

3. Mobile Generates and Sends Login Token
Once the user confirms the login, the mobile app generates a secure, time-limited token. This token:
• Encodes a strict 10-minute expiration
• Is valid for one use only
The app sends this token to the Durable Object via HTTPS, where it is held temporarily until the desktop client retrieves it.
4. Desktop Receives Token and Finalizes Login
The Durable Object transmits the token through the open WebSocket connection to the desktop browser. The browser then uses this token to authenticate against BoxHero’s backend, completing the login process.
Once the token is received and the session is authenticated, the Durable Object triggers cleanup routines to invalidate the session and remove all stored state.
Implementation Details: Managing Sessions and WebSocket Behavior
▶︎ Session State Management
We use Durable Objects to manage one session per QR code. This allows us to enforce strict constraints around session lifecycle and security:
- One WebSocket connection per session
- Sessions are automatically invalidated 10 minutes after creation
- Strict validation of mobile login requests based on geolocation and user agent match
To handle session expiration, we use the Alarm API provided by Cloudflare Durable Objects. Once a session reaches the 10-minute mark, the Durable Object triggers a cleanup routine. All associated data is removed via deleteAll()
so that no lingering state remains beyond the allowed window.
▶︎ WebSocket Resilience
To support real-time communication between desktop and mobile clients, we rely on persistent WebSocket connections initiated by the browser. However, keeping those connections active indefinitely (especially during idle moments) can be expensive and inefficient.
To address this, we use Cloudflare’s WebSocket Hibernation. This feature lets idle WebSocket connections enter a low-resource state, maintaining the session's presence without incurring additional compute cost.
This approach was especially useful during the brief waiting period between the QR code being scanned and the user confirming the login on their mobile device.
▶︎ Security Considerations
Because we’re creating sessions without traditional credentials (i.e. passwords or email verification), QR login required multiple safeguards:
- One-time session IDs: Durable Objects manage isolated sessions that cannot be reused after completion or timeout.
- Metadata verification: Information about the originating desktop (e.g., location, OS, IP address) is used to verify login origin and help users detect suspicious activity.
- Mobile session trust: Tokens are only issued if the mobile session is valid and recently authenticated.
- Token TTL enforcement: Desktop clients reject expired or reused tokens; backend enforces strict issuance timestamp checks.
Together, these measures allow us to deliver a login experience that feels instant while maintaining the same level of security guarantees as our existing authentication flows.
Lessons Learned
Designing QR login pushed us to rethink how we approach authentication across devices when traditional methods like email codes fail silently or create friction. Building the system outside our core backend stack using Cloudflare Workers and Durable Objects allowed us to deliver real-time communication and session coordination without introducing operational complexity.
Key takeaways from the project:
✅ WebSocket architecture doesn’t need to be heavyweight. By offloading it to Workers, we avoided modifying our core stack.
✅ QR login flows feel fast and secure to users, but require tight control over token lifecycle. We focused on expiration logic, metadata validation, and clear mobile UX.
QR login is now available for all BoxHero users.
It’s fast, secure, and avoids the pitfalls of email-based authentication. Looking ahead, we see this approach extending to other trust-based flows, like device linking, approval workflows, and team session management. Durable Objects have proven to be a reliable foundation for coordinating short-lived, high-trust interactions.
We're continuing to refine the experience and exploring ways to improve other parts of BoxHero. Our goal remains the same: solve real user problems with practical engineering and modern infrastructure. 🙂
If you're building similar infrastructure or curious about how Durable Objects scale in production, we’d be happy to exchange notes.