Supabase魔法链接认证(Vanilla JS)问题求助
Supabase魔法链接认证问题解决指南
问题根源
点击魔法链接后URL携带token参数但未完成登录,核心原因是没有解析URL中的认证参数并完成会话初始化——Supabase不会自动处理这一步,需要手动触发登录流程。
解决方案步骤
1. 处理魔法链接回调,完成登录
页面加载时检查URL的hash参数,调用Supabase的getSessionFromUrl方法解析token,完成登录后清理URL并跳转至指定页面。
2. 监听认证状态,同步用户数据
通过onAuthStateChange监听用户登录/登出状态,自动同步用户数据到本地存储,方便后续路由校验。
3. 实现路由保护
编写路由守卫函数,拦截未登录用户访问受保护路由,强制跳转至登录页。
完整实现代码
// *magic link login with supabase* const magicLinkForm = document.getElementById("magic-link-form"); const sendLink = document.getElementById("sendLink"); const userPrompt = document.getElementById("userPrompt"); const cardData = document.getElementById("cardData"); // 初始化Supabase客户端 const _supabase = supabase.createClient( "https://vorgmkkmxuwpruztecpu.supabase.co", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InZvcmdta2tteHV3cHJ1enRlY3B1Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2ODgzMTkzNDQsImV4cCI6MjAwMzg5NTM0NH0.HY_fteEtLcTOZjtD17VkuVfEjjfzBbLcP1Q2784y7cU" ); userPrompt.style.display = "none"; // 处理魔法链接回调,完成登录 async function handleMagicLinkCallback() { const hash = window.location.hash; if (hash.includes("access_token") && hash.includes("type=magiclink")) { const { data, error } = await _supabase.auth.getSessionFromUrl(); if (!error) { // 清理URL中的hash参数,跳转到指定页面 window.location.hash = ""; window.location.href = "http://192.168.100.42:5500"; } else { console.error("登录失败:", error); } } } // 监听认证状态变化,同步用户数据到本地存储 _supabase.auth.onAuthStateChange((event, session) => { if (event === "SIGNED_IN") { localStorage.setItem("user", JSON.stringify(session.user)); console.log("用户已登录:", session.user); } else if (event === "SIGNED_OUT") { localStorage.removeItem("user"); console.log("用户已登出"); } }); // 页面加载时检查魔法链接回调 window.addEventListener("load", handleMagicLinkCallback); // 发送魔法链接表单提交逻辑 magicLinkForm.addEventListener("submit", async (e) => { e.preventDefault(); const email = document.getElementById("email").value; const { data, error } = await _supabase.auth.signInWithOtp({ email, options: { emailRedirectTo: "http://192.168.100.42:5500", }, }); if (error) { console.error("发送魔法链接失败:", error); return; } cardData.style.display = "none"; userPrompt.style.display = "block"; console.log("魔法链接已发送:", data); }); // 路由保护函数:拦截未登录用户访问受保护路由 function protectRoute(protectedPaths) { const currentPath = window.location.pathname; const user = JSON.parse(localStorage.getItem("user")); // 若用户未登录且当前路径在受保护列表中,跳转至登录页 if (!user && protectedPaths.includes(currentPath)) { window.location.href = "/login.html"; // 替换为你的登录页实际路径 } } // 示例:保护/dashboard和/profile路由 protectRoute(["/dashboard", "/profile"]);
关键说明
handleMagicLinkCallback:负责解析URL中的认证参数,完成登录后清理URL并跳转,避免参数残留。onAuthStateChange:实时同步用户登录状态到本地存储,确保页面刷新后仍能快速校验用户身份。protectRoute:可根据实际业务调整受保护路由列表,适配你的页面路径结构。
内容的提问来源于stack exchange,提问作者Jawad Ul Hassan
相关产品推荐
相关产品推荐

