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

如何在SvelteKit中实现路由访问的身份认证校验与跳转?

问题原因

localStorage是浏览器环境专属的API,而SvelteKit中+page.js的load函数默认会在服务器端执行(SSR模式),服务器环境没有localStorage对象,所以会抛出“未定义”的错误。

解决方案

推荐优先用服务器端会话(Cookie)处理登录状态,安全性更高且适配SSR;如果必须依赖客户端存储,也可以强制在浏览器端执行逻辑。

方案一:服务器端Cookie验证(推荐)

将JWT存储在带HttpOnly、Secure标记的Cookie中(避免XSS风险),然后在服务器端代码中读取Cookie并验证登录状态,实现重定向。

1. 单个页面独立处理

在主页和登录页对应的+page.server.js中编写逻辑:

// src/routes/+page.server.js(主页的服务器端逻辑)
export async function load({ cookies, redirect }) {
  const jwt = cookies.get('jwt');
  
  const res = await fetch("[你的认证接口地址]", {
    headers: jwt ? { Authorization: `Bearer ${jwt}` } : {},
    credentials: "include"
  });
  const { logged_in } = await res.json();

  if (!logged_in) {
    throw redirect(302, '/login');
  }

  return { logged_in };
}
// src/routes/login/+page.server.js(登录页的服务器端逻辑)
export async function load({ cookies, redirect }) {
  const jwt = cookies.get('jwt');
  
  const res = await fetch("[你的认证接口地址]", {
    headers: jwt ? { Authorization: `Bearer ${jwt}` } : {},
    credentials: "include"
  });
  const { logged_in } = await res.json();

  if (logged_in) {
    throw redirect(302, '/');
  }

  return { logged_in };
}

2. 全局路由拦截(更高效)

如果需要对所有路由统一处理,用hooks.server.js的handle钩子:

// src/hooks.server.js
export async function handle({ event, resolve }) {
  const jwt = event.cookies.get('jwt');
  const res = await fetch("[你的认证接口地址]", {
    headers: jwt ? { Authorization: `Bearer ${jwt}` } : {},
    credentials: "include"
  });
  const { logged_in } = await res.json();

  const currentPath = event.url.pathname;

  // 已登录用户访问/login,重定向到主页
  if (currentPath === '/login' && logged_in) {
    return new Response(null, {
      status: 302,
      headers: { Location: '/' }
    });
  }

  // 未登录用户访问主页,重定向到登录页
  if (currentPath === '/' && !logged_in) {
    return new Response(null, {
      status: 302,
      headers: { Location: '/login' }
    });
  }

  // 其他路由正常处理
  return resolve(event);
}

方案二:强制客户端执行逻辑(不推荐)

如果必须依赖localStorage,可以关闭当前页面的SSR,让load函数在浏览器端运行:

// src/routes/+page.js 或 src/routes/login/+page.js
export const ssr = false; // 关闭SSR,强制在浏览器端执行

export async function load({ url, redirect }) {
  const jwt = localStorage.getItem('jwt');
  
  const res = await fetch("[你的认证接口地址]", {
    headers: jwt ? { Authorization: `Bearer ${jwt}` } : {},
    credentials: "include"
  });
  const { logged_in } = await res.json();

  if (url.pathname === '/' && !logged_in) {
    throw redirect(302, '/login');
  }
  if (url.pathname === '/login' && logged_in) {
    throw redirect(302, '/');
  }

  return { logged_in };
}

注意:关闭SSR会导致首屏加载变慢,且localStorage中的JWT容易被XSS攻击窃取,存在安全隐患,仅在特殊场景下使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 20:18:34