如何在SvelteKit中验证用户是否已登录(基于JWT的access_token)
问题解决与最佳实践
1. 修复核心报错
你遇到的错误是因为在SvelteKit服务器端代码中,使用全局fetch调用相对URL不符合框架规范,必须改用event.fetch来处理内部路由/代理请求,它会自动适配你的代理配置和路由规则。
修改后的src/hooks.server.ts代码:
import type { Handle } from '@sveltejs/kit'; export const handle: Handle = async ({ event, resolve }) => { const access_token = event.cookies.get('access_token'); if (access_token) { try { // 替换全局fetch为event.fetch const response = await event.fetch('/api/token/user/me', { method: 'GET', headers: { Authorization: `Bearer ${access_token}` } }); // 校验请求是否成功,避免无效数据存入locals if (response.ok) { const user = await response.json(); event.locals.user = user; } else { // Token无效/过期时,清理Cookie并重置用户状态 event.cookies.delete('access_token', { path: '/' }); event.locals.user = null; } } catch (err) { // 捕获网络异常或API错误,避免影响后续请求 console.error('获取用户信息失败:', err); event.locals.user = null; } } else { event.locals.user = null; } return await resolve(event); };
2. 最佳实践优化建议
- 完善错误边界:永远不要忽略API请求的异常情况,比如Token过期、API宕机,及时清理无效状态避免脏数据
- 强化Cookie安全性:设置
access_token时,务必添加httpOnly、secure(生产环境)、sameSite: 'strict'属性,防范XSS和CSRF攻击 - 复用用户数据:通过
+layout.server.ts将locals.user注入所有页面的初始数据,避免多个组件重复发起用户信息请求 - 权限校验分层:hooks仅做基础身份验证,页面级的细粒度权限控制(比如管理员页面)放在对应路由的
load函数中处理 - Token刷新机制:如果你的认证体系包含refresh_token,可在hooks中检测Token过期时自动发起刷新请求,无需用户重新登录
内容的提问来源于stack exchange,提问作者rmarquet21
相关产品推荐
相关产品推荐

