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

SvelteKit JWT认证状态页面刷新不持久问题求助

问题:Svelte页面刷新后认证状态无法持久化

使用Svelte + Node.js开发Web应用,采用JWT令牌实现用户认证,令牌及用户信息存储在Cookie中。当前遇到以下问题:

  • 登录后UI能正常显示Logout按钮,但页面刷新后会变回Login/Registration按钮
  • 控制台能看到令牌和用户数据,但UI无法正确展示登录/登出状态
  • 已尝试用Svelte Store管理状态,但未解决问题
  • 后端通过Postman测试正常,仅前端存在异常

相关代码

stores.ts

import { writable } from 'svelte/store';
 
export const UserId = writable(null);

export const setUserId = (id) => {
    UserId.set(id);
    return UserId;
};

export const Authenticated = writable(false);

export const setUserAuthenticated = (auth) => {
    Authenticated.set(auth);
    return Authenticated;
};
{#if $Authenticated}
    <div class="button-container">
        <Button
                element="a"
                href="/profile"
                variant="outline"
                color="green">Profile
        </Button>
    </div>
    <div class="button-container" on:click={handleSubmit}>
        <Button
                element="a"
                href="/"
                variant="outline"
                color="red">Logout
        </Button>
    </div>
{:else }
    <div class="button-container">
        <Button
                element="a"
                href="/login"
                variant="outline"
                color="green">Login
        </Button>
    </div>
    <div class="button-container">
        <Button
                element="a"
                href="/register"
                variant="outline"
                color="red">Registration
        </Button>
    </div>
{/if}

+layout.server.ts

import type { LayoutServerLoad } from './$types';
import jwt from "jsonwebtoken";

export const load: LayoutServerLoad = async ({ cookies }) => {
    const authToken = cookies.get('auth-token');
    const refreshToken = cookies.get('refresh-token');

    console.log('Auth token in LAYOUT.SERVER::::::::: ', authToken);
    console.log('Refresh token in LAYOUT.SERVER::::::::: ', refreshToken);

    function handleAuthentication(authToken) {
        if (!authToken) {
            console.log('No authToken present');
            return {
                user: null,
                isAuthenticated: false
            };
        }

        try {
            const secretKey = 'farmTokenSecrets';
            const decodedAuthToken = jwt.verify(authToken, secretKey);
            const userId = decodedAuthToken.userId;
            console.log('User ID in LAYOUT.SERVER::::::::: ', userId);
            return {
                user: { userId },
                isAuthenticated: true
            };
        } catch (error) {
            console.error('Error decoding auth-token:', error);
            return {
                user: null,
                isAuthenticated: false
            };
        }
    }

    return handleAuthentication(authToken);
};

解决方案

核心问题:Svelte Store是客户端状态管理工具,不能在服务器端的+layout.server.ts中直接更新。服务器端代码运行在Node.js环境,和浏览器端的Store完全隔离,之前在+layout.server.ts里调用setUserAuthenticated和UserId.set对客户端Store没有任何影响。

正确实现步骤:

  1. 修改服务器端load函数,返回认证状态数据
    如上面修改后的+layout.server.ts,不再操作Store,而是将isAuthenticated和user数据返回给客户端。

  2. 添加客户端+layout.ts,初始化Store
    创建src/routes/+layout.ts,接收服务器端返回的数据,更新客户端Store:

    import type { LayoutLoad } from './$types';
    import { UserId, Authenticated } from '$helpers/stores';
    
    export const load: LayoutLoad = async ({ data }) => {
        // 从服务器端数据初始化客户端Store
        Authenticated.set(data.isAuthenticated);
        UserId.set(data.user?.userId ?? null);
        
        return data;
    };
    
  3. 登录/登出时同步更新Store
    登录成功后,除了设置Cookie,还要调用setUserAuthenticated(true)和setUserId(userId);登出时调用setUserAuthenticated(false)和setUserId(null),同时清除Cookie。

页面刷新时,服务器端会先验证Cookie中的JWT,返回认证状态,客户端layout用这些数据初始化Store,UI就能正确展示登录状态了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 21:35:22