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

如何在SvelteKit与Supabase中实现Cookie身份验证?

SvelteKit + Supabase 身份验证最佳实践(含Cookie持久化)

现有实现的问题

你当前在__layout.svelte中编写的客户端session同步逻辑仅能解决前端运行时的session访问需求,存在两处核心缺陷:

  • 服务端渲染(SSR)阶段无法获取session,所有需要鉴权的服务端逻辑无法正常执行
  • session默认存储在localStorage中,无法实现浏览器重启后的持久化登录,且存在XSS攻击泄露凭证的风险

完整实现步骤

1. 调整客户端逻辑:同步Session到Cookie

修改你现有的__layout.svelte代码,在Supabase认证状态变化时自动写入/清除Cookie:

<script>
  import supabase from "$lib/api";
  import { session } from '$app/stores';
  import { browser } from '$app/env';

  if(browser){
    // 优先使用服务端注入的session,无有效session时再从Supabase客户端拉取
    if (!$session) {
      $session = supabase.auth.session();
    }
    supabase.auth.onAuthStateChange((event, sesh) => {
      $session = sesh;
      if (sesh) {
        // 同步session到cookie,过期时间和Supabase JWT过期时间保持一致
        const expires = new Date(sesh.expires_at * 1000).toUTCString();
        const cookieValue = encodeURIComponent(JSON.stringify(sesh));
        // 生产环境HTTPS下请额外添加Secure属性
        document.cookie = `sb_session=${cookieValue}; path=/; expires=${expires}; SameSite=Lax`;
      } else {
        // 登出时清除cookie
        document.cookie = "sb_session=; path=/; expires=Thu, 01 Jan 1970 00:00:00 UTC; SameSite=Lax";
      }
    });
  }
</script>

2. 配置服务端钩子:解析Cookie注入Session

创建src/hooks.server.js(SvelteKit v1以下版本路径为src/hooks.js),实现请求阶段的Cookie解析与session注入:

export async function handle({ event, resolve }) {
  // 从请求头中提取session cookie
  const cookieHeader = event.request.headers.get('cookie');
  const sbSessionCookie = cookieHeader
    ?.split('; ')
    .find(row => row.startsWith('sb_session='))
    ?.split('=')[1];
  
  if (sbSessionCookie) {
    try {
      event.locals.session = JSON.parse(decodeURIComponent(sbSessionCookie));
    } catch (err) {
      event.locals.session = null;
    }
  } else {
    event.locals.session = null;
  }

  return resolve(event);
}

// 将服务端session同步到前端$session store
export function getSession(event) {
  return {
    user: event.locals.session?.user || null,
    access_token: event.locals.session?.access_token || null
  };
}

3. 路由鉴权配置

如果需要给指定页面添加登录拦截,直接在对应页面的load函数中判断session是否存在即可,示例:

export async function load({ session }) {
  if (!session.user) {
    return {
      status: 302,
      redirect: '/login'
    };
  }
  return {};
}

4. 可选安全优化

如果要完全弃用Supabase默认的localStorage存储,在初始化Supabase客户端时添加persistSession: false配置即可,避免凭证重复存储带来的安全风险。
生产环境使用HTTPS时,给Cookie添加Secure属性,确保Cookie仅在HTTPS请求中传输,进一步降低泄露风险。

内容的提问来源于stack exchange,提问作者Mr.Bill

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 00:45:04