I received a problem report from a user. For them, the login page keeps loading endlessly. Upon closer inspection, I was able to reproduce it with the 1Password plugin. It seems to attempt to log in the user and redirect directly to Home, resulting in continuous switching between /home and /login. The home route is secured with the Auth middleware.
No form is being submitted, as the login opens in a popup.
<script setup>
import {ref} from 'vue'
import {Head, usePage} from '@inertiajs/vue3'
import Auth from '../Layouts/Auth.vue'
import ActionButton from '../Components/Buttons/LoungeActionButton.vue'
const isLoading = ref(false)
const page = usePage()
const login = async () => {
isLoading.value = true
const newWindow = openWindow({
title: 'Login',
url: page.props.auth.oauth_url
})
if (!newWindow) {
alert("The pop-up was blocked by your browser. Please allow popups for this website.");
isLoading.value = false;
}
}
window.addEventListener('message', (e) => {
if (e.origin !== window.origin) return;
location.href = route('test.home');
isLoading.value = false;
}, {once: true});
function openWindow({url = '', title = '', width = 600, height = 720} = {}) {
const screenWidth = window.innerWidth || document.documentElement.clientWidth || screen.width;
const screenHeight = window.innerHeight || document.documentElement.clientHeight || screen.height;
const left = (screenWidth - width) / 2 + window.screenLeft ?? window.screen.left;
const top = (screenHeight - height) / 2 + window.screenTop ?? window.screen.top;
const optionsStr = `width=${width},height=${height},top=${top},left=${left}`;
return window.open(url, title, optionsStr);
}
</script>
<template>
<Head title="Login"></Head>
<Auth>
<div class="text-center">
<h1 class="text-3xl font-medium text-[#0053a0] dark:text-[#3493eb]">
{{ $t('app.name') }}
</h1>
<p class="mb-4 font-light">
{{ $t('For team and network members') }}
</p>
<ActionButton class="w-80" :disabled="isLoading" @click="login">
{{ $t('Log in with your Member ID') }}
</ActionButton>
<div class="mt-12">
<a href="https://legacy.iza.org/conference_files/formLogin"
class="inline-flex items-center text-sm text-slate-400 dark:text-slate-500 pb-[3px] px-1 border-b border-transparent hover:border-slate-400 dark:hover:border-slate-600 hover:text-[#39c] dark:hover:text-[#3493eb] transition duration-200 ease-in-out"
>
<font-awesome-icon :icon="['far', 'right-to-bracket']" class="mr-1" aria-hidden="true"/>
{{ $t('Login for conference participants') }}
</a>
</div>
</div>
</Auth>
</template>
I have already tried checking in the RedirectIfAuthenticated middleware if the query has a code that comes from the login redirect OAuth Server, but as expected, logging out just leads to a loop again.
public function handle(Request $request, Closure $next, string ...$guards): Response
{
$guards = empty($guards) ? [null] : $guards;
foreach ($guards as $guard) {
if (Auth::guard($guard)->check()) {
if ($request->query('code')) {
return redirect(RouteServiceProvider::HOME);
} else {
Auth::guard($guard)->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('/login');
}
}
}
return $next($request);
}
Does anyone know how to solve the problem or is it perhaps a 1Password bug?
return redirect(RouteServiceProvider::HOME);
in your server-sidehandle
method, or thelocation.href = route('test.home');
from your client-sidemessage
event handler?return redirect(RouteServiceProvider::HOME);
The popup doesn't even open and the loop already starts.if ($request->query('code'))
be true? Thecode
is what you get back from the OAuth provider, when they redirect back to your application, is it not?