You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel登录在1Password浏览器插件激活时陷入无限循环求助

问题:登录页面因1Password插件陷入无限加载循环

用户反馈登录页面持续无限加载,排查发现1Password浏览器插件会尝试直接登录并跳转Home页面,导致/login与/home反复切换——Home路由受Auth中间件保护,未登录用户访问会被打回/login,最终形成循环。

登录流程采用弹窗式OAuth实现,无传统表单提交,相关前端代码如下:

<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>

曾尝试在RedirectIfAuthenticated中间件中检查OAuth的code查询参数,但登出后仍会陷入循环,中间件代码如下:

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);
}

解决方案

1. 修复中间件逻辑

当前中间件会在已登录用户访问/login时直接登出并跳转回/login,这会触发1Password再次尝试自动登录,形成循环。调整逻辑为:已登录用户访问/login时直接跳转Home,仅在主动登出请求时执行登出操作。

修改后的中间件代码:

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->routeIs('logout')) {
                Auth::guard($guard)->logout();
                $request->session()->invalidate();
                $request->session()->regenerateToken();
                return redirect('/login');
            }
            // 已登录用户访问登录页直接跳首页
            return redirect(RouteServiceProvider::HOME);
        }
    }

    return $next($request);
}

2. 限制前端自动跳转条件

当前前端message事件监听会无条件跳转Home,需添加登录成功验证,仅在弹窗返回有效登录标识时跳转:

window.addEventListener('message', (e) => {
    if (e.origin !== window.origin) return;
    // 验证弹窗返回的登录成功标识
    if (e.data?.success) {
        location.href = route('test.home');
        isLoading.value = false;
    }
}, {once: true});

同时确保OAuth授权完成后,弹窗向主窗口发送的消息包含success: true标识。

3. 兼容1Password自动检测逻辑

1Password会自动识别登录表单并触发自动操作,可添加隐藏的禁用表单避免插件误判:

<!-- 在登录页面的template中添加 -->
<form style="display: none">
    <input type="email" disabled>
    <input type="password" disabled>
    <button type="submit" disabled></button>
</form>

是否为1Password的Bug?

这并非纯粹的插件Bug,而是1Password自动登录逻辑与无表单登录流程的兼容性问题。插件默认会检测页面中的登录表单并尝试自动填充提交,你的弹窗式登录无传统表单,插件误触发了跳转行为,加上中间件逻辑的缺陷,最终导致循环。

内容的提问来源于stack exchange,提问作者Elbern

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 21:50:54