Kaluna's avatar

Laravel/Vue PWA, magic login link?

Hey everyone,

I've scoured the internet trying to find a solution to this.

So, I am creating a "magic login link" like so:

$url = URL::temporarySignedRoute('login.token', now()->addHour(), ['user' => $user->id]);.

This works fine on desktop—but once the PWA is downloaded, it doesn't work (it does on Chrome, locally mind).

I've tried using protocol urls (web+myapp...). I've tried using a "heartbeat" to check an endpoint to see if the current session is active/logged in—but neither option works reliably enough—or at all.

So, I am hoping that somebody here has a suggestion of how I can get this to work? The idea of the passwordless login, is that the end user can get onto the app quickly so as to reduce friction, as the idea of the app is a "task" manager for mechanics—where time (and patience) is in short supply.

Any suggestions hugely appreciated.

1 like
2 replies
vincent15000's avatar

What do you mean when you say that it works fine on Desktop and not with the PWA ?

Both concepts (desktop and PWA) are not similar.

LaryAI's avatar
Level 58

Certainly! The issue you're hitting is common when combining magic login links (usually via email) with a PWA installed to the device's home screen. The core problem is that clicking a magic login URL sent to email usually opens the user's default browser—not the PWA itself. Even if your backend authenticates the user, the PWA remains in its previous, possibly unauthenticated state.

General Solution Overview

To implement "magic link" login reliably for PWAs, you should build a small token bridge between the browser and your PWA:

1. Magic Link Directs User to a Bridge Page

  • The magic link sent to the user takes them to a dedicated route (e.g., /auth/magic-bridge?token=...) in your web app.
  • This page receives the token (or signed URL/whatever identifier) and handles bridging the login from the web browser to the PWA.

2. Detect Installed PWA and Communicate

Inside /auth/magic-bridge:

a. Use "Web Share Target" API (Newer Browsers)

  • If your PWA is registered as a share target (web+myapp://auth?token=...), clicking the link can open the PWA and pass the token—
  • Downside: not every platform and browser supports custom URL schemes for PWAs.

b. Use Local Storage/IndexedDB Bridge + Periodic Checks

  • On the /auth/magic-bridge page: store the token in localStorage or IndexedDB.
  • In your PWA, on start, poll for this token in localStorage. If found, call your backend to finish authentication (and then clear it).

Sample "bridge" code:

// In magic-bridge page (browser)
const token = new URLSearchParams(window.location.search).get('token');
if (token) {
    localStorage.setItem('magic_login_token', token);
    // Optionally: redirect to PWA homepage for user convenience
    window.location = '/'; // or show further instructions
}
// In your PWA (e.g., App.vue mounted() hook or auth store)
const token = localStorage.getItem('magic_login_token');
if (token) {
    // Send token to backend to authenticate
    axios.post('/api/auth/magic-login', { token })
        .then(() => {
            // On success, remove token and update UI
            localStorage.removeItem('magic_login_token');
        });
}
  • This process allows the PWA to "see" the token from the browser, even if launched separately.

3. Optional: Prompt User

Because you can't force the user directly into your already-installed PWA, show clear instructions on the bridge page, such as:

"Almost there! Please re-open the app to complete your login."

Further Notes

  • If iOS: Add extra instructions, as iOS is stricter with localStorage, background tab suspending, etc.
  • For a seamless UX, you might auto-close the bridge tab/window on desktop.
  • Security: Make your magic tokens short-lived and for one-time use.

Summary

  • A: Magic link opens a "bridge" page in the browser.
  • B: Bridge page writes the login token to localStorage.
  • C: The PWA, on next launch or interval, checks for that token, claims it, logs in.

This pattern is battle-tested for login workflows that cross the gap between browser and installed PWA, despite current web platform limitations.

If you need code samples for backend/Laravel handling the "magic-login", let me know!

Please or to participate in this conversation.