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; };
Navbar.svelte
{#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没有任何影响。
正确实现步骤:
修改服务器端load函数,返回认证状态数据
如上面修改后的+layout.server.ts,不再操作Store,而是将isAuthenticated和user数据返回给客户端。添加客户端
+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; };登录/登出时同步更新Store
登录成功后,除了设置Cookie,还要调用setUserAuthenticated(true)和setUserId(userId);登出时调用setUserAuthenticated(false)和setUserId(null),同时清除Cookie。
页面刷新时,服务器端会先验证Cookie中的JWT,返回认证状态,客户端layout用这些数据初始化Store,UI就能正确展示登录状态了。
内容的提问来源于stack exchange,提问作者Sss
相关产品推荐
相关产品推荐

